content: {-# LANGUAGE GADTs #-}
  
  {- This code, courtesy of Markus Lauer (markus.lauer-2006@lauerit.de)
     was rejected by the sophisticated wobbly-type impl in 6.4.1, and
     with a terrible error message:
       Sample.hs:22:40:
         Couldn't match `MayFail' against `MayFail'
           Expected type: Result s b
           Inferred type: Result MayFail a
         In the first argument of `Return', namely `Fail'
         In a case alternative: Fail -> return Fail
  
     Strangely it is accepted by the simplified impl in GHC 6.5. -}
  
  module Sample where
  
  import Control.Applicative (Applicative(..))
  import Control.Monad (liftM, ap)
  
  data Safe
  data MayFail
  
  data Result s a where
     Ok   :: a   -> Result s       a
     Fail ::        Result MayFail a
  
  newtype M s a = M { unM :: IO (Result s a) }
  
  instance Functor (M s) where
      fmap = liftM
  
  instance Applicative (M s) where
      pure x = M (return (Ok x))
      (<*>) = ap
  
  instance Monad (M s) where
  
    {- this one gives a type error in 6.4.1 -}
    M m >>= k = M (do res <- m
                      case res of
                           Ok x -> unM (k x)
                           Fail -> return Fail
                       )
  
    {- while this one works -}
    -- M m >>= k = M (f m (unM . k))
    --   where
    --     f :: IO (Result s a) -> (a -> IO (Result s b)) -> IO (Result s b)
    --     f m k = do res <- m
    --                case res of
    --                     Ok x -> k x
    --                     Fail -> return Fail
  
  
  
  