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