这是合法的Haskell代码吗?

qua*_*dev 3 haskell

GHC编译顺利,但它在运行时失败了:

many_a x =
    let
        a = 2
    in
        let 
            a = 2*a
        in
            x*a
Run Code Online (Sandbox Code Playgroud)

直觉上,这不应该奏效.但是GHC接受了它.

ehi*_*ird 18

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

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