haskell - 将 state monad 与 costate comonad 结合

标签 haskell functional-programming monads category-theory comonad

如何组合状态单子(monad)S -> (A, S)与 comonad (E->A, E) ?

我尝试了两种明显的组合S -> ((E->A, E), S)(E->S->(A, S), E)但是在任何一种情况下,我都不知道如何为组合定义操作( returnextract ,...等等)。

最佳答案

结合两个单子(monad) OI如果有 O,则产生一个 monad或 I是共指的,即有一个 extract方法。每个comonad是copointed。如果两者都是 O和我是共同的,那么你有两种不同的“自然”方式来获得一个可能不等价的单子(monad)。

你有:

unit_O :: a -> O a
join_O :: O (O a) -> O a
unit_I :: a -> I a
join_I :: I (I a) -> I a

在这里我添加了_O_I为清楚起见加了后缀;在实际的 Haskell 代码中,它们不会存在,因为类型检查器会自行计算出来。

你的目标是证明 O (I O (I a)))是一个单子(monad)。假设 O是共指的,即有一个函数 extract_O :: O a -> a .

然后我们有:
unit :: a -> O (I a)
unit = unit_O . unit_I
join :: O (I (O (I a))) -> O (I a)

当然,问题在于实现 join .我们遵循以下策略:
  • fmap在外 O
  • 使用 extract_O乘坐内部O
  • 使用 join_I将两者结合I单子(monad)

  • 这导致我们
    join = fmap_O $ join_I . fmap_I extract
    

    为了使这项工作,您还需要定义
    newtype MCompose O I a = MCompose O (I a)
    

    并将各自的类型构造函数和解构函数添加到上面的定义中。

    另一种选择使用 extract_I而不是 extract_O .这个版本更简单:
    join = join_O . fmap_O extract_I
    

    这定义了一个新的 monad。我假设你可以用同样的方式定义一个新的共单,但我没有尝试过。

    关于haskell - 将 state monad 与 costate comonad 结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24439917/

    相关文章:

    haskell - 使用StateT s IO a的内存泄漏在哪里?

    functional-programming - 如何在 Erlang 二进制文件中一次高效地设置一位而不需要命令式?

    haskell - 计算列表中满足给定谓词的元素数量

    haskell - 为什么 "return Nothing"什么都不返回?

    haskell - 将列表拆分为排序的子列表

    haskell - 镜头库 : Is there an optic for this?

    haskell - 没有因使用 ‘floor’ 而产生的 (Integral Double) 实例

    android - 如何在启动画面中以编程方式旋转图像而不是使用进度条?

    haskell - 使用 id 定义 fmap 并返回

    .net - 使用单例区分联合制作计算表达式