
Am Freitag 16 April 2010 17:09:07 schrieb Philip Scott:
Philip Scott wrote
The documentation says that, but it does appear to go deeper than just one level:
Debug.Trace Prelude Control.Exception> let a = trace "Hello" 42 Debug.Trace Prelude Control.Exception> let b = trace "Frank" (a * 2) Debug.Trace Prelude Control.Exception> evaluate b Frank Hello 84
Perhaps it specifies WHNF in case you 'evaluate' something which doesn't have a HNF (like a partially applied function?).
It is actually quite interesting what it does in this case:
let f x = trace "jingle" (x * 2) a <- evaluate (f)
:t f
f :: (Num a) => a -> a
:t a
a :: Integer -> Integer
So it does some sort of evaluation - it has decided we're going to be using Integers instead of Nums. I wonder what it is up to there.
Without impredicative polymorphism (whatever that is), you can't get a polymorphic value from an action, so while Prelude Debug.Trace Control.Exception> :t evaluate f evaluate f :: (Num a) => IO (a -> a) , when you bind the result of evaluate f to a name, that is assigned a monomorphic type. Without a type signature, the type variable a is defaulted to Integer. You can (until 6.14) Prelude Debug.Trace Control.Exception> :set -XImpredicativeTypes Prelude Debug.Trace Control.Exception> u <- evaluate f :: IO (forall a. Num a => a -> a) <no location info>: Warning: -XImpredicativeTypes is deprecated: impredicative polymorphism will be simplified or removed in GHC 6.14 Prelude Debug.Trace Control.Exception> :t u u :: (Num a) => a -> a Prelude Debug.Trace Control.Exception> u 4 :: Int jingle 8 Prelude Debug.Trace Control.Exception> u 4 :: Double jingle 8.0 Prelude Debug.Trace Control.Exception> u 4 :: Rational jingle 8 % 1