【问题标题】:Defining Monad of nested monads定义嵌套单子的单子
【发布时间】:2023-03-04 08:30:01
【问题描述】:

我正在尝试为一个类型定义一个 monad 的实例,其定义如下:

type Error a = Either String a
data Outer a = Outer { fromOuter :: Error (Maybe a) } 
Outer 类型的

FunctorsApplicative 实例可以定义为:

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 实例

【问题讨论】:

  • 不幸的是,monad 不会组合。你发现了一个Monad Transformer
  • 似乎 hedis-simple 定义 RedisTx 的方式是不可能为其编写 monad 实例。我想知道是否可以做出更简单的设计决策。

标签: haskell monads


【解决方案1】:

&gt;&gt;= 函数的类型应该是

Outer a -> (a -> Outer b) -> Outer b

由于在 Outer 值是 (Right (Just x)) 对于某些 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

至于你的第二个问题,你不能。给定两个单子MN,它们的组合M N 不能自动变成单子。详情请见this question

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2011-01-13
    • 2019-08-29
    相关资源
    最近更新 更多