Haskell 这是合法的哈斯克尔密码吗?
GHC编译它时没有任何问题,但在运行时失败得很惨:Haskell 这是合法的哈斯克尔密码吗?,haskell,Haskell,GHC编译它时没有任何问题,但在运行时失败得很惨: many_a x = let a = 2 in let a = 2*a in x*a 凭直觉,这不应该起作用。但是GHC接受了它。是的,这是有效的Haskell代码。问题是,第二个表达式中的alet…in实际上是一个新的a;完全可以通过定义一个同名的新变量来隐藏现有变量。但是,它不会影响外部a的值。然而,这通常被认为是不好的风格,
many_a x =
let
a = 2
in
let
a = 2*a
in
x*a
凭直觉,这不应该起作用。但是GHC接受了它。是的,这是有效的Haskell代码。问题是,第二个表达式中的
a
let…in实际上是一个新的a
;完全可以通过定义一个同名的新变量来隐藏现有变量。但是,它不会影响外部a
的值。然而,这通常被认为是不好的风格,因为可能会产生混乱和错误;如果您将-Wall
传递给GHC,它将发出警告
它在运行时“失败”,因为您已将
a
定义为2*a
,这将导致运行时出现无限循环。这是因为懒惰;基本上,(*)
在将两个参数相乘之前对其求值。当然,评估2
效果很好,但是评估a
会使它再次经历相同的过程。同样,允许无限列表(如one=1:one
)的事情也使得这个代码成为一个无限循环。为什么你认为它不合法?它是合法的,但它不符合你的想法。这种误解是我通常更喜欢where
而不是let
…in
的原因之一。