<div dir="ltr">Hi all,<br><br>I've come across some code I just can't figure out how to write appropriately. Below is a silly example that demonstrates what I'm trying to do. I don't really have the appropriate vocabulary to describe the issue, so I'll let the code speak for itself. In particular, I'm trying to understand what the correct type signatures for unwrapMyData and bin should be.<br>
<br>Thanks,<br>Michael<br><br>---<br><br>{-# LANGUAGE MultiParamTypeClasses #-}<br>{-# LANGUAGE ExistentialQuantification #-}<br>{-# LANGUAGE FlexibleInstances #-}<br>{-# LANGUAGE FlexibleContexts #-}<br>class Monad m => MonadFoo x m where<br>
foo :: x -> m a<br><br>data MyData a = forall i. Integral i => MyLeft i<br> | MyRight a<br><br>instance Monad MyData where<br> return = MyRight<br> (MyLeft i) >>= _ = MyLeft i<br> (MyRight x) >>= f = f x<br>
instance Integral i => MonadFoo i MyData where<br> foo = MyLeft<br><br>bar :: MonadFoo Int m => Int -> m String<br>bar 0 = return "zero"<br>bar i = foo i<br><br>baz :: String -> MyData String<br>baz "zero" = MyRight "Zero"<br>
baz _ = MyLeft (-1 :: Integer)<br><br>--This works: unwrapMyData (MyLeft i) = foo (fromIntegral i :: Integer)<br>unwrapMyData (MyLeft i) = foo i -- This is what I'd like to work<br>unwrapMyData (MyRight a) = return a<br>
<br>bin i = do<br> a <- bar i<br> b <- unwrapMyData $ baz a<br> return $ b ++ "!!!"<br><br>instance Show a => MonadFoo a IO where<br> foo = fail . show -- I know, it's horrible...<br><br>
main = do<br> res <- bin 0<br> putStrLn res<br><br></div>