Этот вопрос возникает из-за проблемы, которую Брент Йорги поставил перед OPLSS: напишите функцию f :: (Int -> Int) -> Bool
, которая отличает ] f undefined
из f (\ x -> undefined)
. Во всех наших ответах использовался либо seq
, либо что-то вроде шаблонов взрыва, которые превращают сахар в seq
. Например:
f :: (Int -> Int) -> Bool
f g = g `seq` True
*Main> f undefined
*** Exception: Prelude.undefined
*Main> f (\x -> undefined)
True
В комментарии GHC к seq
говорится, что
e1 `seq` e2
использовался для десахарирования в
case e1 of { _ -> e2 }
, поэтому я попытался удалить сахар вручную. Не сработало:
f' g = case g of { _ -> True }
*Main> f' undefined
True
*Main> f' (\x -> undefined)
True
Зависит ли это поведение от более сложного seq
, описанного в конце комментария , и если да, то как это работает? ? Можно ли написать такой f
без этих примитивов?
x `seq` e2 ==> case seq# x RW of (# x, _ #) -> e2 -- Note shadowing!
e1 `seq` e2 ==> case seq# x RW of (# _, _ #) -> e2