1

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.

Mikhail Glushenkov
  • 14,928
  • 3
  • 52
  • 65
BARJ
  • 1,543
  • 3
  • 20
  • 28
  • 1
    For `m a` to `IO a`, have a look at `liftIO` in `MonadIO`. More generally, `lift` from `MonadTrans`. Otherwise, maybe you'll be interested in the package `mmorph`. – tomferon Oct 17 '13 at 11:54
  • 1
    You're probably aware of this, but just saying: `\x -> return x` is simply `return`, and by the monad laws `v >>= return` must be `v` again, always. So at the moment you have just `funcX = abc` there. – leftaroundabout Oct 17 '13 at 12:06
  • 1
    It's Not Possible By Design. You cannot unwrap IO off a value. It's forever, like diamonds. Perhaps if you tell us what problem you are trying to solve, we'll be able to help you. – n. m. could be an AI Oct 17 '13 at 12:20
  • [How do I convert `IO Int` to `Int`?](http://www.haskell.org/haskellwiki/FAQ#How_do_I_convert_IO_Int_to_Int.3F) – Daniel Wagner Oct 17 '13 at 18:46
  • See also: [How to extract value from monadic action](http://stackoverflow.com/q/8567743/791604) and [taking out a value out of a monad? haskell](http://stackoverflow.com/q/7314789/791604) – Daniel Wagner Oct 17 '13 at 18:51

2 Answers2

7

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.

J. Abrahamson
  • 72,246
  • 9
  • 135
  • 180
-1

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

viorior
  • 1,783
  • 11
  • 16