我正在尝试为类型定义monad的实例,其定义如下:
type Error a = Either String a
data Outer a = Outer { fromOuter :: Error (Maybe a) }
外部类型的Functors 和 Applicative 实例可以定义为:
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中问题的抽象,我试图为RedisTx定义Monad实例
答案 0 :(得分:3)
>>=
功能的类型应为
Outer a -> (a -> Outer b) -> Outer b
由于某些a
的{{1}}值为Outer
,您只有(Right (Just x))
,因为您可以这样做:
x
至于你的第二个问题,你不能。鉴于两个单子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
和M
,他们的作品N
无法自动制作成monad。有关详细信息,请参阅this question。