Haskell的类型系统将数值视为函数?

Lon*_*ong 6 haskell types numeric typeclass

在玩了一下haskell之后我偶然发现了这个功能:

Prelude Data.Maclaurin> :t ((+) . ($) . (+))
((+) . ($) . (+)) :: (Num a) => a -> (a -> a) -> a -> a
Run Code Online (Sandbox Code Playgroud)

(Data.Maclaurin由包向量空间导出.)因此它需要一个Num,一个函数,另一个Num并最终返回一个Num.以下工作有什么神奇之处?

Prelude Data.Maclaurin> ((+) . ($) . (+)) 1 2 3
6
Run Code Online (Sandbox Code Playgroud)

2显然不是一个函数(a-> a)或者我错过了什么?

sth*_*sth 16

Data.NumInstances同一个包的模块定义Num返回数字的函数的实例:

instance Num b => Num (a->b) where
  (+)         = liftA2 (+)
  (*)         = liftA2 (*)
  fromInteger = pure . fromInteger
  ...
Run Code Online (Sandbox Code Playgroud)

在Haskell中,类似的整数字面2是通用的,因此它可以表示任何实例的数字Num:

Prelude> :t 2
2 :: (Num t) => t
Run Code Online (Sandbox Code Playgroud)

将其转换为在特定的上下文所需要的类型的实际数量,fromIntegerNum类调用.

由于上面提到的辅助模块定义了Numfor函数的实例,2现在可以fromInteger使用此处指定的方法将其转换为函数.因此ghci调用fromInteger 2将所需的函数作为问题中构造的第二个参数.然后整个表达式恰好评估为6.