Haskell $! оператор и бесконечные списки

Я читал, что $! оператор строго оценивает ситуацию. Итак, почему это все еще работает?

Prelude> take 10 $! repeat 1
[1,1,1,1,1,1,1,1,1,1]

Я ожидал, что ghc навсегда искоренится, пытаясь оценить бесконечный список 1.

Ответы

Ответ 1

$! заставляет свой второй аргумент использовать слабую головную нормальную форму, что в основном означает, что он вычисляет свой аргумент как внешний конструктор. Таким образом, в вашем случае это не будет заставлять оценивать весь список, а только оценивает внешний конструктор (т.е. Первый) :.

Есть хорошее объяснение нормальной формы против WHNF в Haskell: что такое нормальная форма слабого головы?.

Обратите внимание: если вы принудительно оценили весь список (например, используя оператор $!! из модуля Control.DeepSeq), ваша программа не завершится:

λ: import Control.DeepSeq (($!!))
λ: take 10 $!! repeat 1
^C