Может кто-либо объяснять различие в Haskell между операторами ($)
и ($!)
(знак доллара по сравнению с восклицательным знаком знака доллара)?
Я не видел использование $!
где угодно до сих пор, но при просматривании ссылки Haskell, я заметил ее существование и что она имеет то же самое определение как $
. При попытке некоторых простых операторов в интерпретаторе Haskell (GHCi) я не мог найти различие, и при этом я не мог найти, что любая ссылка на оператор в вершине перечислила учебные руководства при поиске haskell tutorial
.
Так, только из любопытства, каково различие, если вообще?
($!)
- строго функциональное приложение. То есть он оценивает аргумент перед вычислением функции.
Это противоречит нормальному применению ленивых функций в Haskell, например f x
или f $ x
, которые сначала начинают вычислять функцию f
и вычисляют аргумент x
только в случае необходимости.
Например, succ (1 + 2)
задержит добавление 1 + 2
путем создания преобразователя и сначала начнет оценивать succ
. 1 + 2
вычисляется только в том случае, если требуется аргумент succ.
Однако, если вы точно знаете, что аргумент функции всегда будет нужен, вы можете использовать ($!)
, который сначала оценит аргумент в нормальную форму слабой головы, а затем введите функция. Таким образом, вы не создадите целую кучу преобразователей, и это может быть более эффективным. В этом примере succ $! 1 + 2
сначала вычислит 3
, а затем введет функцию succ
.
Обратите внимание, что не всегда безопасно просто заменить обычное функциональное приложение строгим функциональным приложением. Например:
ghci> const 1 (error "noo!")
1
ghci> const 1 $! (error "noo!")
*** Exception: noo!
См. функцию seq, которая принудительно оценивает значение. $! определяется в терминах seq.
Это - запись в блоге, которая показывает некоторые нюансы ее использования.