Как работает seq force?

Предпосылки

Этот вопрос возникает из-за проблемы, которую Брент Йорги поставил перед 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
26
задан Don Stewart 22 June 2011 в 17:14
поделиться