How does GHCi print partially-applied values created from "pure"? - haskell

I've been playing around with Applicative instances in order to figure out how they work. However, I honestly don't understand this behavior.
If I define my own datatype, then apply pure to it with no other arguments, nothing prints out, but it errors if I try to apply something to the result.
ghci> data T = A
ghci> pure A
ghci> pure A 0
<interactive>:21:1:
No instance for (Show T) arising from a use of ‘print’
In a stmt of an interactive GHCi command: print it
However, if I make T an instance of Show, then A is printed out in both cases.
ghci> data T = A deriving (Show)
ghci> pure A
A
ghci> pure A 0
A
What I really don't understand is how pure A can be a value that is printed differently between the two cases. Isn't pure A partially applied?
I do understand why calling pure A 0 errors in the first example and doesn't in the second—that makes sense to me. That's using the ((->) r) instance of Applicative, so it simply yields a function that always returns A.
But how is pure instantiated with only one value when the type of the applicative itself isn't yet known? Furthermore, how can GHC possibly print this value?

GHCi is a little bit peculiar. In particular, when you type an expression at the prompt, it tries to interpret it in two different ways, in order:
As an IO action to execute.
As a value to print out.
Since IO is Applicative, it is interpreting pure A as an IO action producing something of type T. It executes that action (which does nothing), and since the result is not in Show, it does not print anything out. If you make T an instance of Show, then it kindly prints out the result for you.
When you write pure A 0, GHCi sees this:
pure :: Applicative f => a -> f a
pure A :: Applicative f => f T
And since you apply pure A to 0, pure A must be a function a->b for some types a and b, and a must contain 0.
(Num a, Applicative f) => f T ~ (a -> b)
(Note that x ~ y means that x and y unify—they can be made to have the same type.)
Thus we must have f ~ ((->) a) and T ~ b, so in fact GHC infers that, in this context,
pure A :: Num a => ((->) a) T
Which we can rewrite as
pure A :: Num a => a -> T
Well, (->) a is an instance of Applicative, namely "reader", so this is okay. When we apply pure A to 0 we get something of type T, namely A. This cannot be interpreted as an IO action, of course, so if T is not an instance of Show, GHCi will complain.

When you give a value of ambiguous type to the GHCi prompt to evaluate, it tries to default the type in various ways. In particular, it tries whether it can fit an IO a type, in case you want to execute an IO action (see the GHC manual). In your case, pure A defaults to the type IO T. Also:
Furthermore, GHCi will print the result of the I/O action if (and only if):
The result type is an instance of Show.
The result type is not ().

Related

How does GHCi pick an instance of the Monad type class to use for polymorphic actions?

I'm new to Haskell so this might be a noob question.
When I do return 10 >>= return GHCi shows 10. When I check the type of return 10 with :t it just says return 10 :: (Monad m, Num a) => m a, and of I do typeOf return 10 I get an error.
But as far as I understand, Haskell must have used a particular instance of >>= to evaluate return 10 >>= return, so which instance did it use and how did it decide which one to use?
This follows the idea that GHCi is sort of like a giant do block of IO. Whenever you type in something that is an expression it first tries to see if the type of the result can be specialized to something of the form IO a. If it can, it executes the IO action and just prints the result. Only otherwise does it print the result of the expression itself.
To force GHCi to go to whatever specific monad you want, you can add a type annotation. Notice how IO gets treated differently (and the same way as the expression would have been treated without any annotation).
ghci> return 10 >>= return :: Maybe Int
Just 10
ghci> return 10 >>= return :: [Int]
[10]
ghci> return 10 >>= return :: IO Int
10
As an aside, there is an entirely different problem regarding what instance of Num is chosen, and that one has everything to do with defaulting rules and the monomorphism restriction.

Calling show on results from generic functions in ghci

I'm a bit confused by this thing in GHCI when you use functions of a specific type class, but not specifying what concrete type you want. Consider the following code:
pure (1+) <*> pure 1
> 2
The way I understand it, when you type something into GHCI, it evaluates the expression and calls putStrLn . show on it. But how can this be evaluated? Why is this 2? I mean, it makes sense and it's probably 2 for most Applicative instances, but there's no way to know for sure, right? If we check the type of the expression we get:
pure (1+) <*> pure 1 :: (Num b, Applicative f) => f b
OK, fair enough, the types look reasonable, but there was never any type class instance specified, so how did GHCI/Haskell know what function to call when I wrote pure/<*>?
Intuition from other languages tell that this should be an error. Kind of like trying to call an instance method statically in an OOP language (obviously not the same, but it's that kind of feeling I'm getting).
What's going on here?
It's due to two features of ghci:
type defaulting, which resolves Num b => b to Integer (notice that 1 is actually fromInteger 1 and you may define -- but not recommanded -- some numeric data type in which fromInteger 1 + fromInteger 1 == k and show k == "3", so this matters):
the whole ghci runs in IO monad, and if an expression can be instantiated to an IO action, then it will be, so Applicative f => f is resolved to IO. If the expression is of type C1 f => f a, and IO isn't an instance of that type class C1, ghci will raise an ambiguity error.

What is the type of return 5 in Haskell when no context is given?

In this question the OP asks what the type of the expression return 5 is and the answer has already been given in that question: it is a generic type, as can be verified by typing
:t return 5
in the Haskell interpreter:
return 5 :: (Num a, Monad m) => m a
The specific implementation of return is determined by the context in which it appears: type inference will restrict m to a specific monad such as Maybe, [], IO, and so on.
I can also force the interpreter to pick a specific monad by specifying the type, e.g.
Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]
and so on.
Now if I type the expression return 5 without specifying a type, I get:
Prelude> return 5
5
which is quite surprising to me: I would rather have expected the interpreter to tell me that it cannot pick an appropriate implementation of return because it cannot infer the monadic type to be used.
So my question is: what specific monad has Haskell used here? And based on what criteria was this monad chosen?
EDIT
Thanks for the answer! In fact, if I try to compile this program:
module Main
where
a = return 5
main :: IO ()
main = putStrLn "This program should not compile"
I get an error:
No instance for (Monad m0) arising from a use of `return'
The type variable `m0' is ambiguous
Relevant bindings include
a :: m0 Integer (bound at invalid_return.hs:4:1)
Note: there are several potential instances:
instance Monad ((->) r) -- Defined in `GHC.Base'
instance Monad IO -- Defined in `GHC.Base'
instance Monad [] -- Defined in `GHC.Base'
...plus one other
In the expression: return 5
In an equation for `a': a = return 5
So it only works in GHCi for the reasons explained by Jon.
The monad is IO. This is a minor quirk of the behaviour of GHCi. It tries to unify the type of your input with IO a; if it succeeds, it runs that IO action and tries to show the result. If you give it something other than an IO action, it simply tries to show the value.
It’s for the same reason that these produce the same output:
Prelude> "hello"
"hello"
Prelude> print "hello"
"hello"

When are type signatures necessary in Haskell?

Many introductory texts will tell you that in Haskell type signatures are "almost always" optional. Can anybody quantify the "almost" part?
As far as I can tell, the only time you need an explicit signature is to disambiguate type classes. (The canonical example being read . show.) Are there other cases I haven't thought of, or is this it?
(I'm aware that if you go beyond Haskell 2010 there are plenty for exceptions. For example, GHC will never infer rank-N types. But rank-N types are a language extension, not part of the official standard [yet].)
Polymorphic recursion needs type annotations, in general.
f :: (a -> a) -> (a -> b) -> Int -> a -> b
f f1 g n x =
if n == (0 :: Int)
then g x
else f f1 (\z h -> g (h z)) (n-1) x f1
(Credit: Patrick Cousot)
Note how the recursive call looks badly typed (!): it calls itself with five arguments, despite f having only four! Then remember that b can be instantiated with c -> d, which causes an extra argument to appear.
The above contrived example computes
f f1 g n x = g (f1 (f1 (f1 ... (f1 x))))
where f1 is applied n times. Of course, there is a much simpler way to write an equivalent program.
Monomorphism restriction
If you have MonomorphismRestriction enabled, then sometimes you will need to add a type signature to get the most general type:
{-# LANGUAGE MonomorphismRestriction #-}
-- myPrint :: Show a => a -> IO ()
myPrint = print
main = do
myPrint ()
myPrint "hello"
This will fail because myPrint is monomorphic. You would need to uncomment the type signature to make it work, or disable MonomorphismRestriction.
Phantom constraints
When you put a polymorphic value with a constraint into a tuple, the tuple itself becomes polymorphic and has the same constraint:
myValue :: Read a => a
myValue = read "0"
myTuple :: Read a => (a, String)
myTuple = (myValue, "hello")
We know that the constraint affects the first part of the tuple but does not affect the second part. The type system doesn't know that, unfortunately, and will complain if you try to do this:
myString = snd myTuple
Even though intuitively one would expect myString to be just a String, the type checker needs to specialize the type variable a and figure out whether the constraint is actually satisfied. In order to make this expression work, one would need to annotate the type of either snd or myTuple:
myString = snd (myTuple :: ((), String))
In Haskell, as I'm sure you know, types are inferred. In other words, the compiler works out what type you want.
However, in Haskell, there are also polymorphic typeclasses, with functions that act in different ways depending on the return type. Here's an example of the Monad class, though I haven't defined everything:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
fail :: String -> m a
We're given a lot of functions with just type signatures. Our job is to make instance declarations for different types that can be treated as Monads, like Maybe t or [t].
Have a look at this code - it won't work in the way we might expect:
return 7
That's a function from the Monad class, but because there's more than one Monad, we have to specify what return value/type we want, or it automatically becomes an IO Monad. So:
return 7 :: Maybe Int
-- Will return...
Just 7
return 6 :: [Int]
-- Will return...
[6]
This is because [t] and Maybe have both been defined in the Monad type class.
Here's another example, this time from the random typeclass. This code throws an error:
random (mkStdGen 100)
Because random returns something in the Random class, we'll have to define what type we want to return, with a StdGen object tupelo with whatever value we want:
random (mkStdGen 100) :: (Int, StdGen)
-- Returns...
(-3650871090684229393,693699796 2103410263)
random (mkStdGen 100) :: (Bool, StdGen)
-- Returns...
(True,4041414 40692)
This can all be found at learn you a Haskell online, though you'll have to do some long reading. This, I'm pretty much 100% certain, it the only time when types are necessary.

Signature of IO in Haskell (is this class or data?)

The question is not what IO does, but how is it defined, its signature. Specifically, is this data or class, is "a" its type parameter then? I didn't find it anywhere. Also, I don't understand the syntactic meaning of this:
f :: IO a
You asked whether IO a is a data type: it is. And you asked whether the a is its type parameter: it is. You said you couldn't find its definition. Let me show you how to find it:
localhost:~ gareth.rowlands$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Prelude> :i IO
newtype IO a
= GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
-- Defined in `GHC.Types'
instance Monad IO -- Defined in `GHC.Base'
instance Functor IO -- Defined in `GHC.Base'
Prelude>
In ghci, :i or :info tells you about a type. It shows the type declaration and where it's defined. You can see that IO is a Monad and a Functor too.
This technique is more useful on normal Haskell types - as others have noted, IO is magic in Haskell. In a typical Haskell type, the type signature is very revealing but the important thing to know about IO is not its type declaration, rather that IO actions actually perform IO. They do this in a pretty conventional way, typically by calling the underlying C or OS routine. For example, Haskell's putChar action might call C's putchar function.
IO is a polymorphic type (which happens to be an instance of Monad, irrelevant here).
Consider the humble list. If we were to write our own list of Ints, we might do this:
data IntList = Nil | Cons { listHead :: Int, listRest :: IntList }
If you then abstract over what element type it is, you get this:
data List a = Nil | Cons { listHead :: a, listRest :: List a }
As you can see, the return value of listRest is List a. List is a polymorphic type of kind * -> *, which is to say that it takes one type argument to create a concrete type.
In a similar way, IO is a polymorphic type with kind * -> *, which again means it takes one type argument. If you were to define it yourself, it might look like this:
data IO a = IO (RealWorld -> (a, RealWorld))
(definition courtesy of this answer)
The amount of magic in IO is grossly overestimated: it has some support from compiler and runtime system, but much less than newbies usually expect.
Here is the source file where it is defined:
http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.3.0.0/src/GHC-Types.html
newtype IO a
= IO (State# RealWorld -> (# State# RealWorld, a #))
It is just an optimized version of state monad. If we remove optimization annotations we will see:
data IO a = IO (Realworld -> (Realworld, a))
So basically IO a is a data structure storing a function that takes old real world and returns new real world with io operation performed and a.
Some compiler tricks are necessary mostly to remove Realworld dummy value efficiently.
IO type is an abstract newtype - constructors are not exported, so you cannot bypass library functions, work with it directly and perform nasty things: duplicate RealWorld, create RealWorld out of nothing or escape the monad (write a function of IO a -> a type).
Since IO can be applied to objects of any type a, as it is a polymorphic monad, a is not specified.
If you have some object with type a, then it can be 'wrappered' as an object of type IO a, which you can think of as being an action that gives an object of type a. For example, getChar is of type IO Char, and so when it is called, it has the side effect of (From the program's perspective) generating a character, which comes from stdin.
As another example, putChar has type Char -> IO (), meaning that it takes a char, and then performs some action that gives no output (in the context of the program, though it will print the char given to stdout).
Edit: More explanation of monads:
A monad can be thought of as a 'wrapper type' M, and has two associated functions:
return and >>=.
Given a type a, it is possible to create objects of type M a (IO a in the case of the IO monad), using the return function.
return, therefore, has type a -> M a. Moreover, return attempts not to change the element that it is passed -- if you call return x, you will get a wrappered version of x that contains all of the information of x (Theoretically, at least. This doesn't happen with, for example, the empty monad.)
For example, return "x" will yield an M Char. This is how getChar works -- it yields an IO Char using a return statement, which is then pulled out of its wrapper with <-.
>>=, read as 'bind', is more complicated. It has type M a -> (a -> M b) -> M b, and its role is to take a 'wrappered' object, and a function from the underlying type of that object to another 'wrappered' object, and apply that function to the underlying variable in the first input.
For example, (return 5) >>= (return . (+ 3)) will yield an M Int, which will be the same M Int that would be given by return 8. In this way, any function that can be applied outside of a monad can also be applied inside of it.
To do this, one could take an arbitrary function f :: a -> b, and give the new function g :: M a -> M b as follows:
g x = x >>= (return . f)
Now, for something to be a monad, these operations must also have certain relations -- their definitions as above aren't quite enough.
First: (return x) >>= f must be equivalent to f x. That is, it must be equivalent to perform an operation on x whether it is 'wrapped' in the monad or not.
Second: x >>= return must be equivalent to m. That is, if an object is unwrapped by bind, and then rewrapped by return, it must return to its same state, unchanged.
Third, and finally (x >>= f) >>= g must be equivalent to x >>= (\y -> (f y >>= g) ). That is, function binding is associative (sort of). More accurately, if two functions are bound successively, this must be equivalent to binding the combination thereof.
Now, while this is how monads work, it's not how it's most commonly used, because of the syntactic sugar of do and <-.
Essentially, do begins a long chain of binds, and each <- sort of creates a lambda function that gets bound.
For example,
a = do x <- something
y <- function x
return y
is equivalent to
a = something >>= (\x -> (function x) >>= (\y -> return y))
In both cases, something is bound to x, function x is bound to y, and then y is returned to a in the wrapper of the relevant monad.
Sorry for the wall of text, and I hope it explains something. If there's more you need cleared up about this, or something in this explanation is confusing, just ask.
This is a very good question, if you ask me. I remember being very confused about this too, maybe this will help...
'IO' is a type constructor, 'IO a' is a type, the 'a' (in 'IO a') is an type variable. The letter 'a' carries no significance, the letter 'b' or 't1' could have been used just as well.
If you look at the definition of the IO type constructor you will see that it is a newtype defined as: GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
'f :: IO a' is the type of a function called 'f' of apparently no arguments that returns a result of some unconstrained type in the IO monad. 'in the IO monad' means that f can do some IO (i.e. change the 'RealWorld', where 'change' means replace the provided RealWorld with a new one) while computing its result. The result of f is polymorphic (that's a type variable 'a' not a type constant like 'Int'). A polymorphic result means that in your program it's the caller that determines the type of the result, so used in one place f could return an Int, used in another place it could return a String. 'Unconstrained' means that there's no type class restricting what type can be returned and so any type can be returned.
Why is 'f' a function and not a constant since there are no parameters and Haskell is pure? Because the definition of IO means that 'f :: IO a' could have been written 'f :: GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #)' and so in fact has a parameter -- the 'state of the real world'.
In the data IO a a have mainly the same meaning as in Maybe a.
But we can't rid of a constructor, like:
fromIO :: IO a -> a
fromIO (IO a) = a
Fortunately we could use this data in Monads, like:
{-# LANGUAGE ScopedTypeVariables #-}
foo = do
(fromIO :: a) <- (dataIO :: IO a)
...

Resources