`sum (replicate 5 (max 6.7 8.9))` 和 `(sum . replicate 5 . max 6.7) 8.9` 如何得到相同的结果?
How does `sum (replicate 5 (max 6.7 8.9))` and `(sum . replicate 5 . max 6.7) 8.9` get the same result?
使用函数组合重写 (sum . replicate 5 . max 6.7) 8.9
。我们有
(sum . replicate 5 . max 6.7) 8.9
我理解 (sum . replicate 5 . max 6.7)
部分。但是它如何处理 8.9
?
编辑评论:原来,6.7
中的.
不是函数组合运算符,而是小数点!
max 6.7
取 Double
和 returns 取 Double
。 replicate 5
取 Double
并生成 [Double]
。 sum
采用 [Double]
和 returns 类型 Double
。 (在类型推断之后。)
.
只是将所有这些函数链接在一起,所以你剩下一个 Double -> Double
类型的函数。然后将 8.9
传递给该函数。
如果写f . g
,这基本上就是\x -> f (g x)
的简写。由于 (.)
运算符是右结合的,因此您的函数等效于:
= (sum . replicate 5 . max 6.7) 8.9
--------------------------------------
(sum . (replicate 5 . max 6.7)) 8.9
和:
= (sum . (replicate 5 . max 6.7)) 8.9
--------------------------------------------------------
(\x -> sum ((\y -> (replicate 5 (max 6.7 y))) x)) 8.9
所以现在如果我们执行评估,我们会看到:
= (\x -> sum ((\y -> (replicate 5 (max 6.7 y))) x)) 8.9
--------------------------------------------------------
sum ((\y -> (replicate 5 (max 6.7 y))) 8.9)
和:
= sum ((\y -> (replicate 5 (max 6.7 y))) 8.9)
----------------------------------------------
sum (replicate 5 (max 6.7 8.9))
因此函数组合首先将 8.9
作为 max
的第二个参数,然后将所有其他函数应用于某种从右到左的链中的结果。
如果您了解 (sum . replicate 5 . max 6.7)
部分,那么您就会知道它 returns 是一个函数,它对最大数 6.7 和重复 5 次的给定数求和。这个新函数的类型是 Float -> Float.
所以接下来我们将 8.9 应用到这个函数,我们得到最终值。我们可以用更直观的方式来写:
mySum :: Float -> Float
mySum = sum . replicate 5 . max 6.7
result :: Float
result = mySum 8.9
Haskell 中的函数已柯里化。柯里化函数,否则采用两个参数值,您只能使用一个参数值。
f = max 2
f 3
3
当你写 max 2 3
时,它实际上被翻译成带有参数 3 的 (max 2),(max 2) 3 是 Haskell 正在做的事情。
这有助于无点代码。您不必指定函数或函数组合的最终参数,但在调用函数或函数组合时必须提供它。
使用函数组合重写 (sum . replicate 5 . max 6.7) 8.9
。我们有
(sum . replicate 5 . max 6.7) 8.9
我理解 (sum . replicate 5 . max 6.7)
部分。但是它如何处理 8.9
?
编辑评论:原来,6.7
中的.
不是函数组合运算符,而是小数点!
max 6.7
取 Double
和 returns 取 Double
。 replicate 5
取 Double
并生成 [Double]
。 sum
采用 [Double]
和 returns 类型 Double
。 (在类型推断之后。)
.
只是将所有这些函数链接在一起,所以你剩下一个 Double -> Double
类型的函数。然后将 8.9
传递给该函数。
如果写f . g
,这基本上就是\x -> f (g x)
的简写。由于 (.)
运算符是右结合的,因此您的函数等效于:
= (sum . replicate 5 . max 6.7) 8.9
--------------------------------------
(sum . (replicate 5 . max 6.7)) 8.9
和:
= (sum . (replicate 5 . max 6.7)) 8.9
--------------------------------------------------------
(\x -> sum ((\y -> (replicate 5 (max 6.7 y))) x)) 8.9
所以现在如果我们执行评估,我们会看到:
= (\x -> sum ((\y -> (replicate 5 (max 6.7 y))) x)) 8.9
--------------------------------------------------------
sum ((\y -> (replicate 5 (max 6.7 y))) 8.9)
和:
= sum ((\y -> (replicate 5 (max 6.7 y))) 8.9)
----------------------------------------------
sum (replicate 5 (max 6.7 8.9))
因此函数组合首先将 8.9
作为 max
的第二个参数,然后将所有其他函数应用于某种从右到左的链中的结果。
如果您了解 (sum . replicate 5 . max 6.7)
部分,那么您就会知道它 returns 是一个函数,它对最大数 6.7 和重复 5 次的给定数求和。这个新函数的类型是 Float -> Float.
所以接下来我们将 8.9 应用到这个函数,我们得到最终值。我们可以用更直观的方式来写:
mySum :: Float -> Float
mySum = sum . replicate 5 . max 6.7
result :: Float
result = mySum 8.9
Haskell 中的函数已柯里化。柯里化函数,否则采用两个参数值,您只能使用一个参数值。
f = max 2
f 3
3
当你写 max 2 3
时,它实际上被翻译成带有参数 3 的 (max 2),(max 2) 3 是 Haskell 正在做的事情。
这有助于无点代码。您不必指定函数或函数组合的最终参数,但在调用函数或函数组合时必须提供它。