Hi, list!
I want to write function, that will stack `return` as much times, as
necessery. In code, I want
<$> magicLift 2 :: IO Int
<$> magicLift 2 :: Maybe [Int]
both be valid.
My best approach is following (not work)
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
class Monad m => MonadS m where
liftS :: a -> m a
instance (Monad m) => MonadS m where
liftS = return
but
<$> :t liftS 2
liftS 2 :: (Monad m, Num a) => m a
What would you suggest?
--
Best regards, Dmitry Bogatov
Hi Dmitry,
Perhaps you just want monad transformers [1, 2]. If you're not familiar
with them, you should probably read [3].
With transformers you'd be able to do this (and more):
$ return 2 :: IO Int
$ return 2 :: ListT Maybe Int -- this works like Maybe [Int]
$ return 2 :: MaybeT [] Int -- this works like [Maybe Int]
$ runListT $ return 2 :: Maybe [Int]
Just [2]
[1] http://hackage.haskell.org/package/transformers
[2] http://hackage.haskell.org/package/mtl
[3] http://web.cecs.pdx.edu/~mpj/pubs/springschool.html
2013/11/23 Dmitry Bogatov
Hi, list!
I want to write function, that will stack `return` as much times, as necessery. In code, I want <$> magicLift 2 :: IO Int <$> magicLift 2 :: Maybe [Int] both be valid.
My best approach is following (not work)
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-}
class Monad m => MonadS m where liftS :: a -> m a
instance (Monad m) => MonadS m where liftS = return
but <$> :t liftS 2 liftS 2 :: (Monad m, Num a) => m a
What would you suggest?
-- Best regards, Dmitry Bogatov
, Free Software supporter and netiquette guardian. git clone git://kaction.name/rc-files.git --depth 1 GPG: 54B7F00D Html mail and proprietary format attachments are forwarded to /dev/null. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Perhaps you just want monad transformers [1, 2]. If you're not familiar with them, you should probably read [3].
With transformers you'd be able to do this (and more):
$ return 2 :: IO Int $ return 2 :: ListT Maybe Int -- this works like Maybe [Int] $ return 2 :: MaybeT [] Int -- this works like [Maybe Int]
In fact, I read and used transformers a bit. If I understand correctly,
I can only do such things for monads, supported by transformers. So,
I cant get (return 2) :: MyWierdMonad (MyAnotherMonad 2)
Yes, I know, it have little practical use, but I am insterested about
teoretical part of question, magic of ghc.
--
Best regards, Dmitry Bogatov
You could perhaps write MyWierdMonadT and MyAnotherMonadT.
Also, probably layers package [1] is related to what you ask.
But if you actually want arbitrary nested monads like m1 (m2 (m3 (m4 a))),
there's no simple way.
Consider Maybe [MyType Int]. MyType may have or may not have a
Monadinstance. Even more: it can have instance in one module, but not
have in
another. But suppose MyType has a Num instance. Then how this should
work: return
2 :: Maybe [MyType Int]? Should 2 be of type Int or MyType Int?
Note that you can make an instance Num a => Num [a] which makes sense
(lists as polynoms). So the same question arises even for Maybe [Int].
If you **really want to do it** (which I doubt), you can use TH (do
determine how many return's to use, though it's ambiguous anyway).
[1]
http://hackage.haskell.org/package/layers-0.1/docs/Documentation-Layers-Over...
2013/11/23 Dmitry Bogatov
Perhaps you just want monad transformers [1, 2]. If you're not familiar with them, you should probably read [3].
With transformers you'd be able to do this (and more):
$ return 2 :: IO Int $ return 2 :: ListT Maybe Int -- this works like Maybe [Int] $ return 2 :: MaybeT [] Int -- this works like [Maybe Int]
In fact, I read and used transformers a bit. If I understand correctly, I can only do such things for monads, supported by transformers. So,
I cant get (return 2) :: MyWierdMonad (MyAnotherMonad 2)
Yes, I know, it have little practical use, but I am insterested about teoretical part of question, magic of ghc.
-- Best regards, Dmitry Bogatov
, Free Software supporter and netiquette guardian. git clone git://kaction.name/rc-files.git --depth 1 GPG: 54B7F00D Html mail and proprietary format attachments are forwarded to /dev/null.
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
FlexibleContexts, OverlappingInstances, TypeFamilies #-}
class Monad m => Ret a m b where
returnN :: a -> m b
instance (Monad m, a ~ b) => Ret a m b where
returnN = return
instance (Monad m, Monad n, Ret a m b) => Ret a n (m b) where
returnN = return . returnN
boo :: [[[Maybe [Either () [Int]]]]]
boo = returnN 0
Dmitry Bogatov
Hi, list!
I want to write function, that will stack `return` as much times, as necessery. In code, I want <$> magicLift 2 :: IO Int <$> magicLift 2 :: Maybe [Int] both be valid.
My best approach is following (not work)
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-}
class Monad m => MonadS m where liftS :: a -> m a
instance (Monad m) => MonadS m where liftS = return
but <$> :t liftS 2 liftS 2 :: (Monad m, Num a) => m a
What would you suggest?
-- Best regards, Dmitry Bogatov
, Free Software supporter and netiquette guardian. git clone git://kaction.name/rc-files.git --depth 1 GPG: 54B7F00D Html mail and proprietary format attachments are forwarded to /dev/null. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Antonio
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, OverlappingInstances, TypeFamilies #-}
class Monad m => Ret a m b where returnN :: a -> m b
instance (Monad m, a ~ b) => Ret a m b where returnN = return
instance (Monad m, Monad n, Ret a m b) => Ret a n (m b) where returnN = return . returnN
boo :: [[[Maybe [Either () [Int]]]]] boo = returnN 0 Great! Now I know what I do not know. Thanks!
--
Best regards, Dmitry Bogatov
participants (3)
-
Antonio -
Dmitry Bogatov -
Nickolay Kudasov