haskell - 如何指定两个操作在类型类中交换?

标签 haskell typeclass commutativity

我开始阅读this paper on CRDTs ,这是一种通过确保修改数据的操作是可交换的来同时共享可修改数据的方法。在我看来,这将是 Haskell 中抽象的一个很好的候选者 - 为 CRDT 提供一个类型类,指定数据类型和在该类型上交换的操作,然后致力于使库在并发进程之间实际共享更新。

我不知道如何在类型类规范中表达操作必须交换的约定。

举个简单的例子:

class Direction a where
  turnLeft :: a -> a
  turnRight :: a -> a

无法保证 turnLeft . turnRightturnRight . turnLeft 相同。我认为后备方法是指定 monad 法则的等效项 - 使用注释来指定类型系统未强制执行的约束。

最佳答案

您想要的是一个包含证明负担的类型类,类似于下面的伪 Haskell:

class Direction a where
    turnLeft  :: a -> a
    turnRight :: a -> a
    proofburden (forall a. turnLeft (turnRight a) === turnRight (turnLeft a))

这里所有实例都必须提供函数和证明供编译器进行类型检查。 (对于 Haskell 来说)这是一厢情愿的想法,因为 Haskell 没有(嗯,有限的)证明概念。

OTOH,Coq 是一种可以提取到 Haskell 的依赖类型语言的证明助手。虽然我从未使用过Coq's type classes之前,快速搜索是富有成效的,例如:

Class EqDec (A : Type) := {
   eqb : A -> A -> bool ;
   eqb_leibniz : forall x y, eqb x y = true -> x = y }.

所以看起来高级语言可以做到这一点,但是在降低标准开发人员的学习曲线方面可以说还有很多工作要做。

关于haskell - 如何指定两个操作在类型类中交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4521996/

相关文章:

haskell - 是否有用于启用重载字 rune 字的 GHC 扩展?

haskell - 重载函数名称的更简单语法

rust - 需要 Rust 特征边界中的交换操作

logic - A或B = B或A证明(自然演绎)

haskell - 如果我想使用 pretty-print 库来添加颜色,如何将终端中的最后一行输出设为 "refresh"?

Haskell 枚举器 : analog to iteratees `enumWith` operator?

performance - 这个 Haskell 代码是否重用了之前的计算?

rust - Rust 中相同类型的相同特征的多个实现

haskell - 必须手动打开量化的类型类证据?

haskell - 真正无序的折叠包