[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