[Haskell-cafe] Just 3 >>= (1+)?
Tillmann Rendel
rendel at cs.au.dk
Sat May 9 16:36:49 EDT 2009
michael rice wrote:
> Prelude> Just 3 >>= (1+)
Let's check the types.
Prelude> :t (>>=)
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
Prelude> :t Just 3
Just 3 :: (Num t) => Maybe t
Prelude> :t (1 +)
(1 +) :: (Num a) => a -> a
Renaming the variables in the type of (1 +) gives:
(1 +) :: (Num c) => c -> c
Since (Just 3) is the first argument of (>>=), we have to unify the
types (Maybe t) and (m a). This leads to:
m = Maybe
t = a
Since (1 +) is the second argument of (>>=), we have to unify the types
(c -> c) and (a -> m b). This leads to:
c = a = m b
Since we haven't found any inconsistencies, typechecking succeeded, and
we instantiate the types of Just 3, (>>=) and (1 +) to the following
types by applying the substituations we found.
Just 3 :: Num (Maybe b) => Maybe (Maybe b)
(1 +) :: Num (Maybe b) => Maybe b -> Maybe b
(>>=) :: Monad Maybe => Maybe (Maybe b) ->
(Maybe b -> Maybe b) -> Maybe b
And the type of the whole expression is accordingly:
Just 3 >>= (1 +) :: (Monad Maybe, Num (Maybe b)) => Maybe b
Now ghc looks at the constraints, figures out that Monad Maybe is fine,
and complains about Num (Maybe b).
Try the fmap function instead, it has the following type:
Prelude> :t fmap
fmap :: (Functor f) => (a -> b) -> f a -> f b
Since every self-respecting Monad is also a Functor, you can use
fmap (1 +) (Just 3).
Now (a -> b) is unified with (Num a => a -> a), so that the overall type
of the function is (Num a => Maybe a) as you would expect.
Tillmann
More information about the Haskell-Cafe
mailing list