重载类型类函数时出现多个声明错误

Multiple declarations errors when overloading typeclass function

以下代码是重载讲座幻灯片中偏序类型类 (POrd) 函数的代码示例。

尝试 运行 这段代码时,函数 'pcompare' 和运算符出现以下多重声明错误。

> class Eq a => POrd a where
>    pcompare :: a -> a -> Maybe Ordering
>    (~<), (~>), (~<=), (~>=) :: a -> a -> Bool
>
>       -- Minimal complete definition:
>       --      (~<)& (~>) | pcompare
> pcompare x y | x == y       = Just EQ
>              | x ~< y       = Just LT
>              | x ~> y       = Just GT
>              | otherwise    = Nothing
>
> x ~<= y = pcompare x y ==  Just LT || x == y
> x ~<  y = pcompare x y ==  Just LT
> x ~>= y = pcompare x y ==  Just GT || x == y
> x ~>  y = pcompare x y ==  Just GT


我收到以下错误消息:

lecture9.lhs:5:1: error:
    Multiple declarations of `pcompare'
    Declared at: lecture9.hs:2:4
                 lecture9.hs:5:1
  |
5 | pcompare x y | x == y       = Just EQ
  | ^^^^^^^^

lecture9.lhs:10:3: error:
    Multiple declarations of `~<='
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:10:3
   |
10 | x ~<= y = pcompare x y ==  Just LT || x == y
   |   ^^^

lecture9.lhs:11:3: error:
    Multiple declarations of `~<'
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:11:3
   |
11 | x ~<  y = pcompare x y ==  Just LT
   |   ^^

lecture9.lhs:12:3: error:
    Multiple declarations of `~>='
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:12:3
   |
12 | x ~>= y = pcompare x y ==  Just GT || x == y
   |   ^^^

lecture9.lhs:13:3: error:
    Multiple declarations of `~>'
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:13:3
   |
13 | x ~>  y = pcompare x y ==  Just GT
   |   ^^

我不明白是什么导致了这个例子中的多重声明错误,因为它看起来与官方的 PartialOrd 类型类实现非常相似。

正如您问题的评论者所指出的,问题是缩进问题之一。对于它的价值,> 符号是合适的,因为您正在尝试编译一个有文化的 Haskell 文件 (.lhs) 而不是一个常规的 Haskell 文件。 (也就是说,在常规 Haskell 文件 (.hs) 中,它们会导致解析错误。)

在 Haskell 中,“顶级”声明 没有 缩进。例如,POrd class 的定义没有缩进。另一方面,-顶级声明必须缩进。 pcompare 和其他运算符的类型声明是 POrd class 的一部分,因此缩进。

pcompare 和其他运算符的定义也必须缩进,但从技术上讲,它们可以放在两个不同的地方。它们可以为 POrd 的特定 实例 定义,或者它们可以为 POrd [=] 定义为 defaults 39=]。根据定义本身,这些似乎是默认值。

长话短说,如果缩进 pcompare 和其他运算符的定义,就可以开始了。 (请记住,> 仍然需要位于行首,因此在 > 之后添加额外的空格,如 > pcompare x y | x == y ...。)