- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 haskell 的初学者,试图理解 Let vs Where wiki page 。最后有一个示例,在函数定义 fib
的左侧添加参数 x
会更改语义。
fib1 =
let fib' 0 = 0
fib' 1 = 1
fib' n = fib1 (n - 1) + fib1 (n - 2)
in (map fib' [0 ..] !!)
fib2 x =
let fib' 0 = 0
fib' 1 = 1
fib' n = fib2 (n - 1) + fib2 (n - 2)
in map fib' [0 ..] !! x
wiki 页面指出“在第二种情况 [fib2
] 中,fib' 会为每个参数 x 重新定义”。我正在寻找一个适合初学者的解释,解释为什么会发生这种情况,一般来说,是否还有更多这样的隐藏副作用?
维基页面还有一个关于 eta reduction 的解释的链接,它表明表达式及其 eta 约简是等价的。那么,如果 fib2
是 fib1
的 eta 抽象,为什么它们不等价呢?
最佳答案
你的最后一点也许是最重要的 - fib1
和 fib2
确实是 eta 等价的,并且编译器完全可以自由地将一种转变为另一种。由于这种转换对指称语义没有影响,只影响操作语义,因此如果它“改进”了程序的操作语义,则通常将其称为优化。问题是很难说出“改进”的真正含义。
维基页面指出
The compiler cannot know whether you intended this -- while it increases time complexity it may reduce space complexity.
确实如此 - 一般来说,这种“优化”可能不是优化,具体取决于您衡量性能的方式。因此,一般来说,编译器不会执行此优化,如果程序员愿意,则将这样做的负担留给程序员,除非确实确定它确实会提高代码的性能。
这种差异是一种称为共享的特征。在 fib1
中,map fib'
中的 fib'
调用将在 fib1
内部的不同调用之间共享fib'
函数。这意味着只要计算函数,就必须保留整个列表map fib' [0..n]
。在某些情况下,这可能会降低性能,但在这种情况下,它可以为您节省大量递归函数调用。在 fib2
中,每个 map fib'
都是单独计算的,因为参数位于 let
之外。考虑这个程序,即使没有优化,它也相当于 fib1
:
fib3 :: Int -> Integer
fib3 =
let fib' 0 = 0
fib' 1 = 1
fib' n = fib1 (n - 1) + fib1 (n - 2)
in \x -> map fib' [0 ..] !! x
\x -> ..
的位置至关重要 - 这里是 let fib' = .. in\x -> map fib' ..
但是在 fib2
中,它是 \x -> let fib' = .. in map fib' ..
.
Thus it will not float the definition out from under the binding of x.
这显然取决于您使用的特定编译器以及编译程序的方式!我假设这个 wiki 页面是在编译器不够智能来找出这个特定示例的时候编写的,但是使用 GHC 7.10.3 和 -O2
,编译器实际上生成 这两个程序的代码相同。
如果您在没有优化的情况下进行编译或解释,性能差异将变得显而易见。这不是由于单态限制 - 即使您为函数提供单态类型,它仍然存在:
fib1 :: Int -> Integer
fib1 = ..
fib2 :: Int -> Integer
fib2 x = ..
区别很明显:
>:set +s
>fib2 32
2178309
(10.86 secs, 6,063,137,456 bytes)
>fib1 32
2178309
(0.00 secs, 0 bytes)
关于haskell - 在haskell中函数定义的LHS中添加参数的语义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36867004/
我创建了一个用户可以添加测试的字段。这一切运行顺利我只希望当用户点击(添加另一个测试)然后上一个(添加另一个测试)删除并且这个显示在新字段中。 所有运行良好的唯一问题是点击(添加另一个字段)之前添加另
String[] option = {"Adlawan", "Angeles", "Arreza", "Benenoso", "Bermas", "Brebant
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在努力将 jQuery 滚动功能添加到 nav-tab (Bootstrap 3)。我希望用户能够选择他们想要的选项卡,并在选项卡内容中有一个可以平滑滚动到 anchor 的链接。这是我的代码,可
我正在尝试在用户登录后再添加 2 个 ui 选项卡。首先,我尝试做一个之后。 $('#slideshow').tabs('remove', '4'); $("#slideshow ul li:last
我有一个包含选择元素的表单,我想通过选择添加和删除其中一些元素。这是html代码(这里也有jsfiddle http://jsfiddle.net/txhajy2w/):
正在写这个: view.backgroundColor = UIColor.white.withAlphaComponent(0.9) 等同于: view.backgroundColor = UICo
好的,如果其中有任何信息,我想将这些列添加到一起。所以说我有 账户 1 2 3 . 有 4 个帐户空间,但只有 3 个帐户。我如何创建 java 脚本来添加它。 最佳答案 Live Example H
我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。示例: 5、8、10、2,使用 + 或 - 等于 9。5 - 8 = -3 + 10 = 7 + 2 = 9 如果有一个预
我似乎有一个卡住的 git repo。它卡在所有基本的添加、提交命令上,git push 返回所有内容为最新的。 从其他帖子我已经完成了 git gc 和 git fsck/ 我认为基本的调试步骤是
我的 Oracle SQL 查询如下- Q1- select hca.account_number, hca.attribute3, SUM(rcl.extended_amou
我正在阅读 http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingG
我正在尝试添加一个“加载更多”按钮并限制下面的结果,这样投资组合页面中就不会同时加载 1000 个内容,如下所示:http://typesetdesign.com/portfolio/ 我对 PHP
我遇到这个问题,我添加了 8 个文本框,它工作正常,但是当我添加更多文本框(如 16 个文本框)时,它不会添加最后一个文本框。有人遇到过这个问题吗?提前致谢。 Live Link: JAVASCRIP
add/remove clone first row default not delete 添加/删除克隆第一行默认不删除&并获取正确的SrNo(例如:添加3行并在看到问题后删除SrNo.2)
我编码this ,但删除按钮不起作用。我在控制台中没有任何错误.. var counter = 0; var dataList = document.getElementById('materi
我有一个类似数组的对象: [1:数组[10]、2:数组[2]、3:数组[2]、4:数组[2]、5:数组[3]、6:数组[1]] 我正在尝试删除前两个元素,执行一些操作,然后将它们再次插入到同一位置。
使用的 Delphi 版本:2007 你好, 我有一个 Tecord 数组 TInfo = Record Name : String; Price : Integer; end; var Info
我使用了基本的 gridster 代码,然后我声明了通过按钮添加和删除小部件的函数它工作正常但是当我将调整大小功能添加到上面的代码中时,它都不起作用(我的意思是调整大小,添加和删除小部件) 我的js代
title 323 323 323 title 323 323 323 title 323 323 323 JS $(document).keydown(function(e){
我是一名优秀的程序员,十分优秀!