Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused by converting WHNF to NF in Haskell [duplicate]

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?

like image 341
Bogdan Ruzhitskiy Avatar asked Nov 28 '18 10:11

Bogdan Ruzhitskiy


1 Answers

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.

like image 182
chi Avatar answered Oct 12 '22 07:10

chi