首页 > 解决方案 > 为什么我可以直接在 REPL 中从 typeclass 实例调用函数(比如从 Ord 进行比较)?

问题描述

当我在像 GHCI 这样的 REPL 中使用 Prelude 时,我会写

*> compare 5 7
LT

为什么我可以compare直接在 REPL 中调用该函数 ()?

我知道这compare是在 typeclass 中定义的Ord。的 typeclass 定义Ord当然表明它是Eq.

这是我的推理: 5有 type Num a => a,并且Numtypeclass 不是Eq. 还,

Prelude> :t (compare 5)
(compare 5) :: (Num a, Ord a) => a -> Ordering

因此,当我应用数字类型参数时,这里施加了一个额外的约束。当我调用时compare 5 7,参数的类型被缩小到确实有Ord. 我认为缩小发生在与类型类关联的默认具体类型上:在 的情况下Num,这是Integer,它有一个 的实例Real,它有一个 的实例Ord

然而,来自非函数式编程背景,我会想象我必须调用compare其中一个数字(就像在 OOP 中的对象上调用它一样)。如果5Integer,它确实实现Ord了,那么我为什么要调用compareREPL 本身呢?这显然是一个与我的范式转变有关的问题,但我仍然没有得到它。希望有人能解释一下。

标签: haskell

解决方案


这里默认的类型开始发挥作用。解释器可以派生它,5并且7需要具有相同的类型,并且是Ord和类型类的成员Num。a 的默认值NumInteger,因为Integer也是 的一个实例Ord,所以我们可以使用Integer.

解释器因此在这种情况下认为57Integers,因此它可以评估函数并获得LT

GHCi 有一些额外的默认规则,在GHCi 文档中描述。


推荐阅读