som*_*ing -2 binding command-line haskell ghc
我正在尝试学习Haskell,但它有点难,因为我的绑定不会从命令行记住; 我的终端输出如下.
> let b = []
> b
[]
> 1:b
[1]
> b
[]
Run Code Online (Sandbox Code Playgroud)
我不知道为什么这样可以请任何人帮忙.
你期望你的榜样做什么?从你所呈现的内容来看,我没有看到任何令人惊讶的结果.
当然,这个答案对你来说可能是令人惊讶的,或者你不会问.而且我会说实话:我可以猜到你的期望.如果我是对的,你认为输出将是:
> let b = []
> b
[]
> 1:b
[1]
> b
[1]
Run Code Online (Sandbox Code Playgroud)
我对吗?假设我,那么问题是:为什么不呢?
嗯,短版本是"那不是什么(:)".相反,(:)从其参数中创建一个新列表; x:xs是一个新的列表,其第一个元素是x,其余的是相同的xs.但它创建了一个新列表.这就像+创建一个新数字一样,它是参数的总和:是行为
> let b = 0
> b
0
> 1+b
1
> b
0
Run Code Online (Sandbox Code Playgroud)
也很惊讶?(希望不是!)
当然,这开启了下一个问题"好吧,我如何更新b呢?".而这正是Haskell展现其真实色彩的地方:你没有.在Haskell中,一旦变量绑定到某个值,该值就永远不会改变; 就好像所有变量和所有数据类型const(使用C语言或最新的Javascript标准)或val(在Scala中)一样.
Haskell的这个特性 - 它被称为纯功能 - 可能是Haskell与每一种主流语言之间最大的区别.当你不在任何地方处理可变状态时,你必须考虑以一种非常不同的方式编写程序.
例如,为了更远一点,你很可能会尝试下一件事:
> let b = []
> b
[]
> let b = 1 : b
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您打算在打字时打印出来的是什么b?
好吧,记住,变量不会改变!所以答案是:
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,…
Run Code Online (Sandbox Code Playgroud)
永远 - 或直到你击中控制-C并中止.
这是因为let b = 1 : b定义了一个名为的新变量b; 你可能也写过let c = 1 : c.因此,你说" b是一个1后面跟着的列表b"; 因为我们知道什么b是可以代替的,并得到" b是该列表1由后跟1其次是b",等等,直到永远.或者:b = 1 : b所以代替b我们得到b = 1 : 1 : b,然后代替我们得到b = 1 : 1 : 1 : 1 : ….
(Haskell产生无限列表而不是进入无限循环的事实是因为Haskell 是非严格的,更普遍地称为惰性 - 这也可能是Haskell与每种主流语言之间的最大区别.有关详细信息,请在Google或Stack Overflow上搜索"延迟评估".)
所以,最后,我希望你能看出为什么我并不感到惊讶:Haskell不可能更新变量绑定.所以,既然你的定义是let b = [],那么当然最后的结果仍然是[]:-)