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
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to