BARJ
BARJ

Reputation: 2002

Haskell Convert from IO a to m a

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

Answers (2)

J. Abrahamson
J. Abrahamson

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

viorior
viorior

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

Related Questions