这是合法的Haskell代码吗?

时间:2012-03-18 17:13:40

标签: haskell

GHC毫不费力地编译它,但它在运行时失败了:

many_a x =
    let
        a = 2
    in
        let 
            a = 2*a
        in
            x*a

直观地说,不应该工作。但是GHC接受了它。

1 个答案:

答案 0 :(得分:18)

是的,这是有效的Haskell代码。问题在于,第二个a表达式中的let...in实际上是 new a;通过定义具有相同名称的新变量, shadow 现有变量是完全允许的。但是,它不会影响外部a的值。然而,由于存在混淆和错误的可能性,它通常被认为是不好的风格;如果您将-Wall传递给GHC,如果您这样做,它会发出警告。

它在运行时“失败”,因为您已将a定义为2*a,这会在运行时导致无限循环。这是由于懒惰;基本上,(*)在乘以它们之前计算它们的两个参数。当然,评估2可以正常工作,但评估a会导致它再次经历相同的过程。允许无限列表(如ones = 1:ones)的相同内容使得此代码成为无限循环。