Це декларація суворості. По суті, це означає, що при створенні значення структури даних її слід оцінювати у тому, що називається "слабкою головою нормальної форми". Давайте подивимось на приклад, щоб ми могли побачити, що це означає:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
f
Вищенаведена функція , коли оцінюється, повертає "сповіщення": тобто код, який потрібно виконати, щоб з'ясувати його значення. На той момент Foo ще не існує, а лише код.
Але в якийсь момент хтось може спробувати заглянути всередину нього, ймовірно, через відповідність шаблону:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Це дозволить виконати достатньо коду, щоб зробити те, що йому потрібно, і не більше. Таким чином, він створить Foo з чотирма параметрами (тому що ви не можете заглянути всередину без його існуючих). По-перше, оскільки ми її тестуємо, нам потрібно оцінити весь шлях4
, де ми розуміємо, що він не відповідає.
Друге не потрібно оцінювати, оскільки ми його не тестуємо. Таким чином, замість того , 6
зберігається в цьому осередку пам'яті, ми будемо просто зберігати код для можливої подальшої оцінки, (3+3)
. Це перетвориться на 6, лише якщо хтось на це подивиться.
Третій параметр, однак, має !
перед собою, тому суворо оцінюється: (4+4)
виконується і8
зберігається в цьому місці пам'яті.
Четвертий параметр також суворо оцінюється. Але ось дещо стає складним: ми оцінюємо не повністю, а лише слабку нормальну форму голови. Це означає , що ми з'ясовуємо , чи є це Nothing
або Just
що - то, і зберігати, але ми не йти далі. Це означає, що ми зберігаємо не, Just 10
а насправді Just (5+5)
, залишаючи гроно всередині не оціненим. Це важливо знати, хоча я думаю, що всі наслідки цього виходять за рамки цього питання.
Ви можете коментувати аргументи функцій так само, якщо ввімкнути BangPatterns
розширення мови:
f x !y = x*y
f (1+1) (2+2)
поверне шматок (1+1)*4
.