我正在尝试创建代数类型类的“层次结构”,如下所示:
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因此,群是么半群,么半群是半群。但是,我得到的错误是这些类看不到它们父类的函数。
这些错误让我恼火,因为我假设通过编写(例如) class (Semigroup a) => Monoid a,类Monoid a应该能够看到函数(.*)。此外,前言中的foldr1类型没有限制,所以我假设foldr1可以在这种情况下工作。
发布于 2011-07-14 08:50:06
Haskell不允许您声明(或强制执行)公式的项(看起来您想这样做)。这是因为一个非常实际的原因:在像Haskell这样丰富的编程语言中,证明任意项之间的等价性是不可判定的。检查人工构建的证明通常是可以确定的,但在编程时必须编写和跟踪这些证明也有些恼人。
尽管如此,如果这是您想要经常做的事情,有一些语言可以实现这一点;要搜索的术语是“依赖类型”。例如,Coq和Agda可能是目前最流行的两种依赖类型语言,这两种语言都会使编写一个只有良好的、遵守法律的半群(或么半群)的类型变得非常简单。
发布于 2011-07-13 16:29:31
我不知道你到底想做什么。
如果您试图在Semigroup中为foldr1提供一个默认值,并在Monoid中为(.*)提供一个默认值,那么您就无法做到。
foldr1在前言中被定义为一个非类型类函数,所以在Semigroup(.*)是Semigroup类的一部分时,您不能给它一个局部定义。可以在Semigroup实例中给出它的值,也可以在Semigroup类中给出它的默认值,但不能在的Monoid类(或Monoid实例)中给出它的值如果您试图在Semigroup中为(.*)提供一个默认值,在Monoid中为identity提供一个默认值,那么您就使用了错误的语法。
相反,尝试像这样的东西
class Semigroup a where
(.*) :: a -> a -> a
(.*) = {-something-}或
class Semigroup a where
(.*) :: a -> a -> a
x .* y = {-something-}https://stackoverflow.com/questions/6675912
复制相似问题