GHC毫不费力地编译它,但它在运行时失败了:
many_a x =
let
a = 2
in
let
a = 2*a
in
x*a
直观地说,不应该工作。但是GHC接受了它。
答案 0 :(得分:18)
是的,这是有效的Haskell代码。问题在于,第二个a
表达式中的let...in
实际上是 new a
;通过定义具有相同名称的新变量, shadow 现有变量是完全允许的。但是,它不会影响外部a
的值。然而,由于存在混淆和错误的可能性,它通常被认为是不好的风格;如果您将-Wall
传递给GHC,如果您这样做,它会发出警告。
它在运行时“失败”,因为您已将a
定义为2*a
,这会在运行时导致无限循环。这是由于懒惰;基本上,(*)
在乘以它们之前计算它们的两个参数。当然,评估2
可以正常工作,但评估a
会导致它再次经历相同的过程。允许无限列表(如ones = 1:ones
)的相同内容使得此代码成为无限循环。