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

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"

Related

'Referencing' typeclass functions

I'm a beginner and I'm trying to use Hoed to trace Haskell evaluations, because maybe it will further help my learning process.
I saw in their examples code like this
isEven :: Int -> Bool
isEven = observe "isEven" isEven'
isEven' n = mod2 n == 0
I was thinking how could I observe in order to trace an instance defined function like >>= for example.
I wrote something like
bind' = observe "bind'" (>>=)
and of course I've got an error
* Ambiguous type variable 'm0' arising from a use of '>>='
prevents the constraint '(Monad m0)' from being solved.
Relevant bindings include
bind' :: m0 a0 -> (a0 -> m0 b0) -> m0 b0 (bound at my.hs:46:1)
Probable fix: use a type annotation to specify what 'm0' should be.
These potential instances exist:
...
Should I / How could I use a type annotation in order to specify which Monad instance's (e.g. Reader, State etc.) >>= function
It looks like you have found the infamous MonomorphismRestriction. More info. The links do a great job of explaining what the MonomorphismRestriction is and how it works.
You're not wrong to expect that writing bind' with no signature should "just work". However, sometimes the compiler needs a bit of help. In short, due to the MonomorphismRestriction, GHC tries to take the nominally polymorphic signature of bind' :: Monad m => m a -> (a -> m b) -> m b, and make it less polymorphic by instantiating some of the type variables.
In your case, it looks like the compiler wants to make bind' only work for one specific Monad m. Without your real code, I can't say for sure, but consider this example:
import Debug.Trace
main :: IO ()
main = (>>=) (return "hello") print
bind' = trace "bind" (>>=)
The compiler produces an error similar to yours: Ambiguous type variable m0
However, if you use bind':
import Debug.Trace
main :: IO ()
main = bind' (return "hello") print
bind' = trace "bind" (>>=)
no error! That's because GHC is inferring that m should be IO since bind' is used in the IO monad.
Alternatively, you can tell GHC to turn off the MonomorphismRestriction:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Debug.Trace
main :: IO ()
main = (>>=) (return "hello") print
bind' = trace "bind" (>>=)
and it compiles just fine!

What is the default type evaluation of MonadPlus in Haskell?

I have the following code:
import Control.Monad
coin :: MonadPlus m => m Int
coin = return 0 `mplus` return 1
If I evaluate coin :: Maybe Int on the interpreter, it prits Just 0. That's normal because of the implementation of Maybe as instance of MonadPlus.
If I evaluate coin :: [Int]on the interpreter, it prints [0, 1], because the implementation of mplus on list is an append.
But if I evaluate coin, without any type decorators, it prints 0. Why? What type does the interpreter 'converts' coin to evaluate it?
This code is extracted from: http://homes.sice.indiana.edu/ccshan/rational/S0956796811000189a.pdf
Yeah, this is a not super-well documented corner of ghci. When you enter an expression into ghci, it uses the expression's type to decide what to do:
IO (): Run the action, do nothing further.
Show a => IO a: Run the action and print the result.
any other IO a: Run the action, do nothing further.
anything else: wrap the whole expression with print.
How does it decide which of these types a thing has? Easy: it tries to unify the type of your expression which each of the above signatures in turn and solve all resulting constraints. (For the cognoscenti: this is in addition to the extended defaulting rules! This explains why it appears to be defaulting the m, even though neither the standard defaulting rules nor the extended defaulting rules say what default to use.)
So, since your expression does not unify with IO () but does unify with Show a => IO a, ghci finds m ~ IO (and a ~ Int) during unification, discovers that there is a MonadPlus IO (and a Show Int) instance to resolve the constraints, runs your action, and prints the result.
GHCi (but not GHC in general) will, in the absence of a signature specifying otherwise, specialise polymorphic type constructors to IO whenever possible. IO actions at the prompt, in turn, are executed and have their results monadically bound to the it variable, which is then printed (i.e. do { it <- action; print it }) as long as there is a Show instance for the result type (cf. Daniel Wagner's answer). For more details, have a look at the I/O actions at the prompt and The it variable sections of the User's Guide.
In your specific case, it happens that there is a MonadPlus instance for IO. You get return 0 from it because mplus for IO only executes the second action if the first one throws an exception. One demonstration:
GHCi> readLn `mplus` readLn :: IO Integer
0
0
GHCi> readLn `mplus` readLn :: IO Integer
foo
1
1
GHCi> readLn `mplus` readLn :: IO Integer
foo
bar
*** Exception: user error (Prelude.readIO: no parse)

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.

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

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 ().

Ambiguous Types, and Defaults for Overloaded Numeric Operations

import Data.Dynamic
default(Integer,Double)
a :: Num a => a
a = 5
-- show :: Show a => a -> String
-- toDyn :: Typeable a => a -> Dynamic
main :: IO ()
-- main = print $ show a -- *** THIS LINE WORKS WELL
main = print $ toDyn a -- *** THIS LINE LEADS TO AN AMBIGUOUS TYPE ERROR
I don't understand why the first "main" version works, and not the second.
Is there someone who can help me ?
Thanks in advance for your reply.
From the Haskell report:
In situations where an ambiguous type is discovered, an ambiguous type variable, v, is defaultable if:
v appears only in constraints of the form C v, where C is a class, and
at least one of these classes is a numeric class, (that is, Num or a subclass of Num), and
all of these classes are defined in the Prelude or a standard library
Your example fails because unlike Show, Typeable is not one of the classes specified in the third point, so no defaulting is performed.

Resources