虽然,正如 jozefg 所说,它们本身是等价的,但当与局部变量绑定结合使用时,它们可能会导致不同的执行行为。考虑
f, f' :: Int -> Int -> Int
有两个定义
f a x = μ*x
where μ = sum [1..a]
和
f' a = \x -> μ*x
where μ = sum [1..a]
这些肯定看起来是等价的,并且肯定会产生相同的结果。
GHCi,版本 7.6.2:http ://www.haskell.org/ghc/ :? 寻求帮助
...
[1 of 1] 编译 Main (def0.hs, 解释)
好的,加载的模块:Main。
*Main> sum $ map (f 10000) [1..10000]
2500500025000000
*Main> sum $ map (f' 10000) [1..10000]
2500500025000000
但是,如果您自己尝试此操作,您会发现 withf
会花费大量时间,而 withf'
您会立即获得结果。原因是它f'
是以提示 GHC 编译它的形式编写的,以便f' 10000
在开始将它映射到列表之前进行实际评估。在该步骤中,该值μ
被计算并存储在 的闭包中(f' 10000)
。另一方面,f
被简单地视为“两个变量的一个函数”;(f 10000)
仅存储为包含参数的闭包,10000
并且一μ
开始根本不计算。仅当map
应用于(f 10000)
列表中的每个元素时,才会计算整体,这对于 中的每个元素都sum [1..a]
需要一些时间。和[1..10000]
f'
,这不是必需的,因为μ
是预先计算的。
原则上,公共子表达式消除是 GHC 能够自行完成的优化,因此即使使用f
. 但你不能指望它。