gol*_*enk 5 syntax lambda haskell lambda-calculus
在Haskell中编写一些lambda函数时,我最初编写的函数如下:
tru = \t f -> t
fls = \t f -> f
Run Code Online (Sandbox Code Playgroud)
但是,我很快从网上的例子中注意到这些函数经常被写成:
tru = \t -> \f -> t
fls = \t -> \f -> f
Run Code Online (Sandbox Code Playgroud)
具体而言,传递给函数的每个项都有自己的\
,->
而不是上面的.检查这些类型时,它们看起来是一样的.我的问题是,它们是相同的还是它们在某种程度上确实存在差异?不仅仅是这两个功能,而且它对一般的功能有什么影响?非常感谢!
Dan*_*zer 14
它们是相同的,哈斯克尔自动咖喱的事情让一切语法不错.以下都是等效的**
foo a b = (a, b)
foo a = \b -> (a, b)
foo = \a b -> (a, b)
foo = \a -> \b -> (a, b)
-- Or we can simply eta convert leaving
foo = (,)
Run Code Online (Sandbox Code Playgroud)
如果你想成为惯用语,请选择第一个或最后一个.引入不必要的lambdas有利于教学curry,但在实际代码中只会增加语法杂乱.
然而,在原始的lambda演算(不是Haskell)中大多数人工咖喱
\a -> \b -> a b
Run Code Online (Sandbox Code Playgroud)
因为人们不会手工编写很多lambda演算,而当他们这样做时,他们往往会坚持使用未经修饰的lambda演算来保持简单.
**模拟单态限制,不管怎样都不会影响你的类型签名.
但是,正如jozefg所说,它们本身是等价的,当与局部变量绑定结合使用时,它们可能会导致不同的执行行为.考虑
f, f' :: Int -> Int -> Int
Run Code Online (Sandbox Code Playgroud)
有两个定义
f a x = ?*x
where ? = sum [1..a]
Run Code Online (Sandbox Code Playgroud)
和
f' a = \x -> ?*x
where ? = sum [1..a]
Run Code Online (Sandbox Code Playgroud)
这些肯定看起来相当,并且肯定会产生相同的结果.
GHCi,版本7.6.2:http ://www.haskell.org/ghc/:?求助
...
[1/1]编译Main(def0.hs,解释)
好的,加载的模块:Main.
*Main> sum $ map(f 10000)[
1..10000 ] 2500500025000000
*Main> sum $ map(
f'10000 )[ 1..10000 ] 2500500025000000
但是,如果你自己尝试一下,你会注意到f
需要花费很多时间,而f'
你会立即得到结果.原因是它f'
以一种形式写入,提示GHC编译它,以便f' 10000
在开始将其映射到列表之前实际进行评估.在该步骤中,?
计算该值并将其存储在闭包中(f' 10000)
.另一方面,f
简单地将其视为"两个变量的一个函数"; (f 10000)
仅存储为包含参数的闭包,10000
并且?
最初根本不计算.仅当map
应用于(f 10000)
列表中的每个元素时,sum [1..a]
才会计算整体,这需要一些时间用于每个元素[1..10000]
.同f'
,这是没有必要的,因为?
是预先计算的.
原则上,共同子表达式消除是GHC能够自行完成的优化,因此即使使用类似的定义,您有时也可能获得良好的性能f
.但你不能指望它.
归档时间: |
|
查看次数: |
1949 次 |
最近记录: |