return Just
has a type of Monad m => m (a -> Maybe a)
Correct, and applying something to it, e.g., return Just 3
– which is equivalent to (return Just) 3
– implies that return Just
must be a function and therefore its type, m (a -> Maybe a)
, must correspond to a function type. So, the Monad
instance for (->) r
is used.
The TypeApplications
extension can help to understand what's happening here:
ghci> :set -XTypeApplications
ghci> :type return @((->) _)
return @((->) _) :: a -> w -> a
Essentially, the particular type of return
for the Monad
instance you are using is:
return :: a -> w -> a
When passing Just
to return
as in return Just
– since you are applying the function – the first parameter of the return
type goes away, and its type is inferred to be a -> Maybe a
because that is the type of Just
:
ghci> :type return @((->) _) Just
return @((->) _) Just :: w -> (a -> Maybe a)
So, the particular type of return Just
for the monad of functions is:
return Just :: w -> (a -> Maybe a)
Finally, passing 3
results in return Just 3 :: a -> Maybe a
.
return
within the whole expression, with my handy Forall What? trick:let { it :: forall what. _; it = (return :: what) Just 3 } in it
will tell you that this instance ofreturn
has the type(a -> Maybe a) -> Integer -> a -> Maybe a
, where theInteger
comes from defaulting. – Leilanileininger