Reputation: 2002
I want to convert a monadic value into a monadic value of a other Monad class.
Lets say I have a instance declaration:
instance ClassM TypeT where
funcX = abc >>= \x -> return (x)
ClassM : is a own monad defined class
TypeT : is a own defined type/data with a monad instance implementation
abc : is of type IO a
how do i convert the monadic value of abc::IO a
to a monadic value of classM m => m a
aka m1 a -> m2 a (where m1 is not m2)(example: IO 5 -> Just 5)
my implementation of funcX is obviously not correct. If it is possible, what should be the correct implementation?
Thank you for your time and help.
Upvotes: 2
Views: 2085
Reputation: 74354
Monad
the class represents all things which are monads---it's an adjective more than a noun. If you'd like to convert a particular monad into a value which is generic in all monads that type would look like one of these
Monad m => IO a -> m a
Monad m => Maybe a -> m a
Monad m => [a] -> m a
Monad m => Either e a -> m a
and it's in general impossible, though one type of very special monads has this property.
Another thing you might do is use a Monad
transformer which IO
at the bottom. This means that you layer another monad "on top of" IO
. This lets you have the general operation
lift :: MonadTrans t => m a -> t m a -- notice that t takes two parameters
lift :: IO a -> MyTransformer IO a -- specializing the generic function
and, depending on what MyTransformer
is, the specific operation
runMyTransformer :: MyTransformer m a -> m a
runMyTransformer :: MyTransformer IO a -> IO a -- specialized
For instance, the very simplest MonadTrans
is IdT
.
newtype IdT m a = IdT { runIdT :: m a } deriving Functor
instance Monad m => Monad (IdT m) where
return a = IdT (return a)
IdT ma >>= f = IdT (ma >>= runIdT . f)
instance MonadTrans IdT where
lift ma = IdT ma
Giving us the operations
lift :: IO a -> IdT IO a
runIdT :: IdT IO a -> IO a
which are just inverses of one another, in this case. In general the behavior can be much more complex.
Upvotes: 8
Reputation: 1803
Monad "class" it is not an "class" from objects.
You are asking about Comonads
->Monad
transformation: Comonad package
convert :: (Comonad w, Monad m) => w a -> m a
convert = return . extract
In any case you can't have comonad from IO
You could use some hackery using unsafePerormIO
Upvotes: -1