Haskell。使用约束定义 class 的实例

Haskell. Using constraint to define an instance of a class

在尝试理解 Haskell 中的实例时,我做了这个例子。 Integer 部分运行良好,但不适用于 Float 实例。我认为最好创建 Num 类型的单个实例(这样方块适用于所有 Num)。我想我必须将 Num 作为约束添加到我的 class 声明中,但我无法弄清楚实例会是什么样子。据我了解,class 上的约束强制任何实例都属于该类型(根据约束)。

class Square a where
    area :: a -> a

instance Square Integer where
    area a = a*a

instance Square Float where
    area a = a*a

I think it is better to make a single instance of the type Num...

不一定,除非你想为 Num 类型定义 class 只有 (然后你不需要 class,只需将其 area :: Num a => a->a 作为顶级函数即可。

以下是创建此类通用实例的方法:

instance (Num a) => Square a where
  area a = a*a

这不是 Haskell98,但它确实适用于广泛使用的 -XFlexibleInstances-XUndecidableInstances 扩展。

问题:如果你还想添加,比如说,

instance Square String where
  area str = concat $ replicate (length str) str

您有两个 重叠实例。这就是一个问题:一般来说,编译器无法决定两个这样的实例中哪一个是正确的。同样,GHC 具有做出最佳猜测的扩展(-XOverlappingInstances-XIncoherentInstances),但与 Flexible/UndecidableInstances 不同的是,它们是 generally avoided.

因此我建议制作单独的实例Square IntSquare IntegerSquare Double。它们不难写,对吧?