Я читал, что $! оператор строго оценивает ситуацию. Итак, почему это все еще работает?
Prelude> take 10 $! repeat 1
[1,1,1,1,1,1,1,1,1,1]
Я ожидал, что ghc навсегда искоренится, пытаясь оценить бесконечный список 1.
Ответ 1
$! заставляет свой второй аргумент использовать слабую головную нормальную форму, что в основном означает, что он вычисляет свой аргумент как внешний конструктор. Таким образом, в вашем случае это не будет заставлять оценивать весь список, а только оценивает внешний конструктор (т.е. Первый) :.
Обратите внимание: если вы принудительно оценили весь список (например, используя оператор $!! из модуля Control.DeepSeq), ваша программа не завершится: