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.
No. However, you can have functions that return a trivial value.
The ++ operator is the list concatenation operator which takes two lists as operands and "combines" them into a single list.
(->) is often called the "function arrow" or "function type constructor", and while it does have some special syntax, there's not that much special about it. It's essentially an infix type operator. Give it two types, and it gives you the type of functions between those types.
return is actually just a simple function in Haskell. It does not return something. It wraps a value into a monad. Looks like return is an overloaded function.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With