Ore*_*lom 1 syntax haskell parentheses
我有一种情况,Haskell缺少括号可以很好地编译,但进入无限循环。这是我的代码,其中的工作版本已被注释掉:
$ cat main.hs
fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n =
let
fib_n_minus_2 = fib n-2
-- fib_n_minus_2 = fib (n-2)
fib_n_minus_1 = fib (n-1)
in
fib_n_minus_2+
fib_n_minus_1
main :: IO ()
main = putStrLn $ show $ fib 7
Run Code Online (Sandbox Code Playgroud)
当我编译它时,一切都很好,但是当我运行生成的程序时,它被卡住了。这是为什么?我想象编译器会进行解析fib n,然后继续查看-2 fib_n_minus_1应该在哪里停止并发出错误,对吗?
fib_n_minus_2 = fib n-2
Run Code Online (Sandbox Code Playgroud)
手段
fib_n_minus_2 = (fib n)-2
Run Code Online (Sandbox Code Playgroud)
并不是
fib_n_minus_2 = fib (n-2)
Run Code Online (Sandbox Code Playgroud)
请注意,这(fib n)-2是一个完全有效的表达式。
(fib n) -2 fib_n_minus1 ...由于fib_n_minus1 ...从下一行开始并缩进了与前一行完全相同的数量,因此未进行解析,因此它是该构造的下一个绑定let。
实际上,您可以假装在实际解析开始之前,缩进用于在绑定周围插入显式花括号,并在它们之间插入分号,如下所示:
let {
fib_n_minus_2 = fib n-2 ;
-- fib_n_minus_2 = fib (n-2)
fib_n_minus_1 = fib (n-1)
}
in
fib_n_minus_2+
fib_n_minus_1
Run Code Online (Sandbox Code Playgroud)
在该in部分中let,只能有一个表达式,因此缩进规则不适用,并且这两行被解析为一个表达式fib_n_minus_2 + fib_n_minus_1。
总之,您的代码在不减少参数的情况下调用自身n,从而导致了无限递归。