In a simple example, converting WHNF to NF by printing works fine
Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3
But in a case, the type is not declared it doesn't work.
Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _
Can you explain in some details why conversion doesn't work in the last case?
Since in GHCi the monomoprhism restriction is disabled, the last x
is a polymorphic value of type x :: Num a => a
. So it is not a simple integer, but a kind-of function DictNum a -> a
which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double
will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x
is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int)
, then x
is being recomputed twice: GHC in general will not "cache" the WHNF at type Int
for successive computations. This is similar to f 3 + f 3
, where f 3
is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.