假设我定义了这个函数:
f = ($ 5)
Run Code Online (Sandbox Code Playgroud)
然后我可以申请它:
> f (\x -> x ^ 2)
25
Run Code Online (Sandbox Code Playgroud)
它的类型是:
:t f
f :: (Integer -> b) -> b
Run Code Online (Sandbox Code Playgroud)
这是有道理的,它将一个函数作为参数,并返回应用于该函数的函数Integer 5.
现在我定义这个函数:
g = flip f
Run Code Online (Sandbox Code Playgroud)
我希望这没有意义,因为它f是单个参数的函数.
但是,检查其类型:
:t g
g :: b -> (Integer -> b -> c) -> c
Run Code Online (Sandbox Code Playgroud)
所以现在g是2个参数的函数!
将它应用于某些值:
> g [2, 4, 6] (\x y -> x:y)
[5,2,4,6]
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?什么是flip ($ 5)真正的意思?
遵循以下类型:
($ 5) :: (Int -> a) -> a
flip :: (x -> y -> z) -> y -> x -> z
Run Code Online (Sandbox Code Playgroud)
但由于->是右结合,类型x -> y -> z相当于x -> (y -> z),所以
flip :: (x -> (y -> z)) -> y -> x -> z
($ 5) :: (Int -> a) -> a
Run Code Online (Sandbox Code Playgroud)
所以x ~ (Int -> a)和(y -> z) ~ a,所以代回:
($ 5) :: (Int -> (y -> z)) -> (y -> z)
Run Code Online (Sandbox Code Playgroud)
并简化
($ 5) :: (Int -> y -> z) -> y -> z
Run Code Online (Sandbox Code Playgroud)
所以
flip ($ 5) :: y -> (Int -> y -> z) -> z
Run Code Online (Sandbox Code Playgroud)
这相当于你看到的类型(虽然我用Int而不是Integer保存打字).
这就是说,($ 5)当传递给flip需要2个参数的函数时,获取专门的类型.拥有像($ 5) const,在哪里const :: a -> b -> a和那样的东西是完全有效的($ 5) const :: b -> Int.所有($ 5)这一切都是5作为函数的参数应用,不一定是函数的参数.这是部分应用程序的示例,其中并非所有参数都提供给函数.这就是为什么你可以做的事情map (subtract 1) [1, 2, 3].
如何使用的一个例子flip ($ 5)是:
> flip ($ 5) 2 (**)
25.0
> flip ($ 5) 1 (-)
4.0
> let f x y = (x, y)
> flip ($ 5) 1 f
(5, 1)
Run Code Online (Sandbox Code Playgroud)
混淆源于多态函数的"参数数量"的松散概念.例如,很有可能这样说
f :: (Integer -> b) -> b
Run Code Online (Sandbox Code Playgroud)
有一个参数(一个函数).然而,更精确的说法f是具有至少一个参数的函数.这是因为b由于多态性,类型变量可以用任何类型替换,从而产生例如
f :: (Integer -> String) -> String
f :: (Integer -> Double) -> Double
...
Run Code Online (Sandbox Code Playgroud)
这些确实是具有一个参数的函数,但也适用于例如
f :: (Integer -> (String -> Double)) -> (String -> Double)
Run Code Online (Sandbox Code Playgroud)
哪里b已被功能类型取代String -> Double.这种替换使得第二个参数以一种看似神奇的方式"出现":在返回a之前,f可以采用第一个参数(二元函数Integer -> String -> Double),然后是第二个参数(a String)Double.
请注意,当多态类型以... -> b某种类型变量结束时,总会出现此现象b.
让我以琐事结束:"许多"论证如何具有身份功能id?嗯,直觉上我会说一个,但让我检查......
> id (+) 3 4
7
> id id id id id (+) 3 4
7
Run Code Online (Sandbox Code Playgroud)
......也许很多人都是更好的答案.
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |