一方面,数字文字如2
实际上读作fromInteger 2 :: Num a => a
so 可以表示任何类型的值Num a => a
,意思是任何类型in类型类别Num
,即除其他外还有一个特殊版本fromInteger
定义返回实际类型的实际值,从整数转换而来2
:
> :i Num
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
As Haskell 教程 https://www.haskell.org/tutorial/numbers.html指出(在 10.3 中),
一个整数(不带小数点)实际上等价于应用fromInteger
到数字的值作为Integer
.
另一方面,($)
有类型
> :t ($)
($) :: (a -> b) -> a -> b
所以我们有
fromInteger 2 :: Num a1 => a1
($) :: (a -> b) -> a -> b
--------------------------------------------
($) 2 :: Num (a -> b) => a -> b
所以它是一个函数,它也必须是in类型类Num
.
通常情况并非如此,但 Haskell 不知道您是否可以导入某个定义此类实例的模块:
instance Num (a -> b) where
....
fromInteger n = ....
....
因此它在类型检查时允许这种可能性,只有这样,看到任何地方都没有定义这样的实际实例,它才会出错that.
例如,按照提示@augustss https://stackoverflow.com/users/649287/augustss在评论中,
instance (Num b) => Num (a -> b) where
(+) f g x = f x + g x
(*) f g x = f x * g x
abs f x = abs (f x)
negate f x = negate (f x)
signum f x = signum (f x)
fromInteger n = const (fromInteger n)
让我们写(sin + 2 * cos^2) x
.