我正在尝试创建代数类型类的"层次结构",如下所示:
class Semigroup a where
(.*) :: a -> a -> a
foldr1 (.*) = foldl1 (.*) -- GHCi error: "`foldr1' is not a (visible) method of class `Semigroup'"
class (Semigroup a) => Monoid a where
identity :: a
(.*) identity = id :: a -> a -- GHCi error: "`.*' is not a (visible) method of class `Monoid'"
class (Monoid a) => Group a where
inverse :: a -> a
Run Code Online (Sandbox Code Playgroud)
因此,群是幺半群,幺半群是半群.但是,我得到的错误是类无法看到其父类的功能.
这些错误让我感到困惑,因为我认为通过编写(例如)class (Semigroup a) => Monoid a类Monoid a可以看到该函数(.*).而且,foldr1Prelude中的类型没有约束,所以我认为这foldr1将在这种情况下起作用.
Haskell不允许您在术语上声明(或强制执行)方程式(就像您想要的那样).这是一个非常实际的原因:证明编程语言中任意项之间的平等性与Haskell一样丰富是不可判定的.检查人工构造的证明通常是可判定的,但是在编程时必须编写和跟踪这些证明也有点烦人.
尽管如此,如果这是你想要定期做的事情,那么有些语言可以实现这一目标; 搜索的术语是"依赖类型".例如,Coq和Agda目前可能是两种最受欢迎的依赖类型语言,并且每种语言都会使编写仅由良好的守法半群(或幺半群)居住的类型变得简单.