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

1

13

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.

Sobranje answered 13/1, 2015 at 22:38 Comment(2)
I'm surprised it doesn't infer a :: (Num b, Monad m) => m bSoiree
If you want to compile the program, enable -XNoMonomorphismRestriction :)Wismar
S
24

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"
Slipnoose answered 13/1, 2015 at 22:43 Comment(3)
Ok, so the result is of type IO Int. This makes sense.Sobranje
@Sobranje No, IO Integer. The number is defaulted according to Haskell's normal defaulting rules.Abeyance
@kosmikus: See my extra example: 5 has indeed gotten type Integer.Sobranje

© 2022 - 2024 — McMap. All rights reserved.