定义嵌套 monad 的 Monad
Defining Monad of nested monads
我正在尝试为一个类型定义一个 monad 实例,其定义如下:
type Error a = Either String a
data Outer a = Outer { fromOuter :: Error (Maybe a) }
Functors 和 Applicative 类型的 Outer 实例可以定义为:
instance Functor Outer where
f `fmap` (Outer fa) = Outer $ fmap (fmap f) $ fa
instance Applicative Outer where
pure = Outer . pure . pure
(Outer l) <*> (Outer r) = Outer $ do
el <- l
er <- r
return $ el <*> er
但是,我正在努力定义 bind 来为这种类型定义 Monad 实例:
instance Monad Outer where
return = pure
(Outer l) >>= f = ??????
进一步的问题是:
如何将以上概括为
data Outer m n a = Outer { fromOuter :: m (n a) }
这个问题是hedis-simple where I am trying to define Monad instance for RedisTx
中一个问题的抽象
你的 >>=
函数的类型应该是
Outer a -> (a -> Outer b) -> Outer b
因为在某些 x
的 Outer
值为 (Right (Just x))
的情况下,您只有一个 a
,您可以这样做:
instance Monad Outer where
return = pure
(Outer l) >>= f = case l of
Left e -> Outer (Left e)
Right Nothing -> Outer (Right Nothing)
Right (Just x) -> f x
关于你的第二个问题,你不能。给定两个 monad M
和 N
它们的组合 M N
不能自动变成 monad。有关详细信息,请参阅 this question。
我正在尝试为一个类型定义一个 monad 实例,其定义如下:
type Error a = Either String a
data Outer a = Outer { fromOuter :: Error (Maybe a) }
Functors 和 Applicative 类型的 Outer 实例可以定义为:
instance Functor Outer where
f `fmap` (Outer fa) = Outer $ fmap (fmap f) $ fa
instance Applicative Outer where
pure = Outer . pure . pure
(Outer l) <*> (Outer r) = Outer $ do
el <- l
er <- r
return $ el <*> er
但是,我正在努力定义 bind 来为这种类型定义 Monad 实例:
instance Monad Outer where
return = pure
(Outer l) >>= f = ??????
进一步的问题是:
如何将以上概括为
data Outer m n a = Outer { fromOuter :: m (n a) }
这个问题是hedis-simple where I am trying to define Monad instance for RedisTx
中一个问题的抽象你的 >>=
函数的类型应该是
Outer a -> (a -> Outer b) -> Outer b
因为在某些 x
的 Outer
值为 (Right (Just x))
的情况下,您只有一个 a
,您可以这样做:
instance Monad Outer where
return = pure
(Outer l) >>= f = case l of
Left e -> Outer (Left e)
Right Nothing -> Outer (Right Nothing)
Right (Just x) -> f x
关于你的第二个问题,你不能。给定两个 monad M
和 N
它们的组合 M N
不能自动变成 monad。有关详细信息,请参阅 this question。