微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

索引单子的高阶编码是如何工作的?

如何解决索引单子的高阶编码是如何工作的?

定义索引 monad a la Atkey 的常用方法是:

class IxMonad m where
  ireturn :: a -> m i i a
  ibind   :: m i j a -> (a -> m j k b) -> m i k b

McBride 的工作中发现了另一种方法(也被他 here 讨论过):

type f :-> g = forall i. f i -> g i

class MonadIx (m :: (state -> *) -> (state -> *)) where
  returnIx    :: f :-> m f
  flipBindIx  :: (f :-> m g) -> (m f :-> m g)

flipBindIx 的类型与 bindIx :: forall i. m f i -> (forall j. f j -> m g j) -> m g i 同构。正常的 Haskell monad 表征 m :: * -> *(而“正常”索引的 monad 表征 m :: state -> state -> * -> *),而 MonadIx 表征 monad m :: (state -> *) -> state -> *。这就是为什么我称后者为“高阶”(但如果有更好的名字,请告诉我)。

虽然这在一定程度上有意义,并且我可以看到两种编码之间的某些结构相似性,但我在一些事情上遇到了困难。以下是一些看似相关的问题:

  • 基本上,我只是不明白如何使用 MonadIx 编写一个简单的索引状态 monad——IxMonad 中的那个看起来就像常规状态 monad,带有更一般的类型。

  • 相关地,在之前链接的 SO 问题中,Kmett discusses 是一种从 IxMonad 中“恢复”MonadIx 的力量的方法。然而,该技术并未完全展示(而且我无法再编译相关代码)。

  • MonadIxIxMonad 强。这表明应该存在从任何 IxMonad m => m i o a 到某个 MonadIx m => m f(或者是 m f i?)的映射,但不是相反,对吗?那是什么映射?

  • 最后,MonadIx 的定义中充满了参数化。但是 IxMonad 动作可以自由地对传入状态的形状提出要求,如 m :: IxMonad m (a,i) i aMonadIx 中的此类操作如何?

解决方法

我只是不明白如何使用 MonadIx 编写一个简单的索引状态 monad——在 IxMonad 中的那个看起来就像常规状态 monad,具有更通用的类型。

McBride 风格的索引 monad 是关于量化运行时不确定性。如果普通 monad m a 对返回 a 的计算进行建模,则索引 monad m a i 对从 state* i 开始并返回 a j 的计算进行建模对于某些未知输出状态 j。关于 j,您唯一可以说的是它满足谓词 a

*我在这里使用了“状态”、“输入”和“输出”这三个词。

这就是 McBride 的 bind 具有更高等级类型的原因:

mcBind :: m a i -> (forall j. a j -> m b j) -> m b i

延续 forall j. a j -> m b j 必须与 j 无关,超出了它在运行时检查 a j 所能学到的。 (对于返回多个 a 的非确定性 monad,它们中的每一个的 j 可能不同。)

McBride 来自 the Outrageous Fortune paper 的运行示例是关于文件 API,它可能成功返回打开的文件或可能失败(如果文件不存在)。 the Hasochism paper 中还有另一个关于平铺窗口管理器的示例 — 您有一个 2D 框,它可能由彼此相邻放置的较小框组成。您可以深入查看单个框并用其他框替换它们。您不知道每个单独的盒子在静态上有多大,但是当用另一个盒子替换一个盒子时,它们必须具有相同的大小。

因此索引状态 monad (State i j a) 采用已知的输入状态 i 并产生已知的输出状态 j,只是不适合 strong> 用于 McBride 风格的索引 monad。 mcBind 的类型是错误的,因为它丢弃了有关输出状态的信息。

[T] 这里应该是从任何 IxMonad [到] MonadIx 的映射,但不是相反,对吗?那是什么映射?

相反。 McBride 的索引 monad 比 Atkey 的更强大——如果你有一个 m :: (i -> *) -> i -> * 的实例为 MonadIx,你总是可以想出一个对应的 n :: i -> i -> * -> * 的实例为 IxMonad . (Surprisingly the reverse is also true。)这在 McBride 的论文(“天使、恶魔和鲍勃”)的第 5 节中有详细说明。简而言之:

-- McBride wittily pronounces this type "at key"
data (a := i) j where
    V :: a -> (a := i) i

newtype Atkey m i j a = Atkey { getAtkey :: m (a := j) i }

instance MonadIx m => IxMonad (Atkey m) where
    ireturn a = Atkey (returnIx (V a))
    ibind (Atkey m) f = Atkey $ m `bindIx` (\(V a) -> getAtkey (f a))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?