Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In GHCi, why can't I show `pure 1` in REPL?

I tried to assign a lifted value to a.

λ> :m Control.Applicative
λ> let a = pure 1

When I evaluated a in REPL, it prints 1.

λ> a
1

Therefore, I thought there may be an implementation of show for a, and tried this:

λ> show a

But the GHCi throws an error:

<interactive>:70:1-4:
    No instance for (Show (f0 a0)) arising from a use of ‘show’
    The type variables ‘f0’, ‘a0’ are ambiguous
    Note: there are several potential instances:
      instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      instance (Show a, Show b) => Show (a, b) -- Defined in ‘GHC.Show’
      instance (Show a, Show b, Show c) => Show (a, b, c)
        -- Defined in ‘GHC.Show’
      ...plus 32 others
    In the expression: show a
    In an equation for ‘it’: it = show a

Does anyone have any ideas about this?

like image 422
Hanfei Sun Avatar asked May 26 '15 17:05

Hanfei Sun


1 Answers

GHCi is defaulting the Applicative f => f to IO. When you do

λ> a
1

you actually run an IO Integer action such as

λ> let a = return 1
λ> a
1

GHCi by default prints the result of IO actions. Hence the 1 in the result line. (Quite confusingly, this 1 is not the value of a, nor the output of running a as an IO action -- just the returned value of the latter.)

GHCi uses a sophisticated heuristics to handle user input. First, it tries to show it, possibly defaulting some type classes like numeric ones. This fails in your case. When that fails, it tries to see if the input is an IO action. In such case, the action is run and, if the result can be showed, it is printed.

Note that this GHCi magic only happens at the top level. When you try to show a, GHCi tries its magic on the whole show a, not on a, so the same effect does not happen.

like image 159
chi Avatar answered Sep 17 '22 14:09

chi