没有实例(Num(Int - > Int))来自文字"5"

Zhe*_*lov 4 haskell

我有以下功能:

f :: (Int -> Int) -> Int
f = undefined
Run Code Online (Sandbox Code Playgroud)

现在,我想打电话f5(这是不正确的):

f 5
Run Code Online (Sandbox Code Playgroud)

显然,这不应该编译,因为5不是从功能IntInt.所以我希望有一个错误信息Couldn't match expected type Int -> Int with Int.

但相反,我得到:

No instance for (Num (Int -> Int)) arising from the literal `5'
In the first argument of `f', namely `5'
In the expression: f 5
In an equation for `it': it = f 5
Run Code Online (Sandbox Code Playgroud)

为什么Num会出现在这里?

chi*_*chi 12

5是类型类中的任何类型Num.这些类型包括Int,Double,Integer,等.

Num 默认情况下,函数不在类型类中.然而,Num用户可以添加功能的实例,例如以逐点方式定义两个功能的总和.在这种情况下,文字5可以代表常数五功能.

从技术上讲,字面意思是fromInteger 5,它5是一个Integer常数.f 5因此,实际上是调用f (fromInteger 5),它试图将五个转换为Int -> Int.这需要一个实例Num (Int -> Int).

因此,GHC不会在其错误中声明5不能成为一个函数(因为它可能是,如果用户声明它,提供一个合适的fromInteger).它只是正确地指出,没有Num找到整数函数的实例.

  • @Jefffrey另外"5也是Show的一个实例" - 这是什么意思?5不是任何事物的实例 - 它不是一个类型,它是一个类型为`Num a => a`的值(而不是`Show a => a`或其他任何东西). (6认同)
  • 我不同意这个答案,特别是在"正确"的部分.`5`也是`Show`的一个实例.为什么它没有失败:"没有(Show(Int - > Int))的实例"? (2认同)
  • @Jefffrey因为节目与它无关.如果`Int - > Int`是`Num`的实例,那意味着`5`可以是`Int - > Int`类型(因为5可以是任何类型的`Num`的实例).如果`Int - > Int`是`Show`的一个实例,那么它并不意味着它,因此没有理由将它出现在错误消息中. (2认同)