0

I read Why :sprint always prints a "_"? but I seem to be encountering something else.

ghci> sum = foldl (+) 0
ghci> let total = sum [1..1000000]
ghci> :sprint total
total = _ -- This is expected due to lazy eval
ghci> print total
500000500000
ghci> :sprint total
total = _ -- This is NOT expected since total has been evaluated.
ghci> :set -XMonomorphismRestriction -- recommended by one of the other answers.
ghci> :sprint total
total = _
ghci> print total
50000005000000
ghci> :sprint total
total = _
ghci> :sprint sum
sum = _
ghci> ints = [1..5]
ghci> :sprint ints
ints = _
ghci> print ints
[1,2,3,4,5]
ghci> :sprint ints
ints = [1,2,3,4,5] -- Yay!

Useful info:

ghci> :show
options currently set: none.
base language is: Haskell2010
with the following modifiers:
  -XNoDatatypeContexts
  -XNondecreasingIndentation
GHCi-specific dynamic flag settings:
other dynamic, non-language, flag settings:
  -fexternal-dynamic-refs
  -fignore-optim-changes
  -fignore-hpc-changes
  -fimplicit-import-qualified
warning settings:

and

$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 9.0.2

So the question then is: why and what can I do to "fix" this? I'm reading along with https://andrew.gibiansky.com/blog/haskell/haskell-syntax/

Nero gris
  • 562
  • 7
  • 15

1 Answers1

0

Try defining total after enabling MonomorphismRestriction extension.

ghci> :set -XMonomorphismRestriction 
ghci> sum = foldl (+) 0
ghci> let total = sum [1..1000000]
ghci> :sprint total
total = _
ghci> print total
500000500000
ghci> :sprint total
total = 500000500000

Or you can give a specific type to total (without MonomorphismRestriction extension).

ghci> sum = foldl (+) 0
ghci> let total = sum [1..1000000] :: Int
ghci> :sprint total
total = _
ghci> print total
500000500000
ghci> :sprint total
total = 500000500000

The thing is, under NoMonomorphismRestriction (the default), the type of total will be (Num a, Enum a) => a. GHCi evaluates it every time if the type of a value is polymorphic like this. So :sprintf cannot print the evaluated value.

When you give it a specific type, :sprintf can print the evaluated value. Note that the type of total will become Integer with MonomorphismRestriction.

snak
  • 6,483
  • 3
  • 23
  • 33