我是新来的Haskell和考虑使用的功能应用与$
的一个简单的例子。
这看起来非常简单 - 它需要一个功能,并将其应用到一个值。
因此,这是有道理的:
> (+3) $ 2
5
这也有道理:
> ($) (+3) 2
5
这是有道理的,因为第一个参数是函数,第二个参数是值。
现在,使用$
使局部功能的考虑。
综观类型,这是有道理的 - 它只是需要一个Num
类型值b
:
> :t ($) (+3)
($) (+3) :: Num b => b -> b
但在这里就是我迷路了 - 这里发生了什么?:
> :t ($) (2)
($) (2) :: Num (a -> b) => a -> b
我本来期望的第一个参数需要是一个函数,而不是一个简单的民值。
因此,这里是我的问题:
Num (a -> b)
语法是什么意思?($)
的一个例子,与类似($) (2)
开始?谢谢!
在一方面,数字文字像2
实际上读作fromInteger 2 :: Num a => a
这样可以表示类型Num a => a
,这意味着,任何类型,是在类型类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
作为the Haskell Tutorial把它(10.3),
一个整数数字(不带小数点)实际上相当于
fromInteger
的到数字作为Integer
的值的应用程序。
在另一方面,($)
有型
> :t ($)
($) :: (a -> b) -> a -> b
因此,我们有
fromInteger 2 :: Num a1 => a1
($) :: (a -> b) -> a -> b
--------------------------------------------
($) 2 :: Num (a -> b) => a -> b
所以这是一个功能,这也必须是在类型类Num
。
通常情况下,这不是如此,但哈斯克尔不知道,如果你可以导入一些模块,它确实定义这样的实例:
instance Num (a -> b) where
....
fromInteger n = ....
....
因此它允许这种可能性的类型检查,也只有这样,看到有定义的任何地方没有这样的实际情况下,它的错误了这一点。
例如,下面从@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
。