Haskell说我的守卫有一个解析错误

Haskell说我的守卫有一个解析错误,haskell,whitespace,guard,pattern-guards,Haskell,Whitespace,Guard,Pattern Guards,过去几天我一直在和Haskell玩,我决定给Fibonacci序列下一个基本的定义。所以我写了这段代码: main = do fib :: (Integral a) => Int -> Int fib x | x == 0 = 0 | x == 1 = 1 | x >= 2 = fib (x - 2) + fib (x - 1) do { print (fib 5) } 我收到一条错误消息说: 4:17:

过去几天我一直在和Haskell玩,我决定给Fibonacci序列下一个基本的定义。所以我写了这段代码:

main = do
    fib :: (Integral a) => Int -> Int
    fib x
        | x == 0 = 0
        | x == 1 = 1
        | x >= 2 = fib (x - 2) + fib (x - 1)
    do { print (fib 5) }
我收到一条错误消息说:

4:17: parse error on input `|'
我怀疑制表符有错误,所以我尝试了我能找到的所有空格修复,但我就是找不到问题所在

编辑:所以我按照人们的建议做了,现在我有了这个代码:

fib :: (Integral a) => Int -> Int
main = do
    fib x
        | x == 0 = 0
        | x == 1 = 1
        | x >= 2 = fib (x - 2) + fib (x - 1)
    print (fib 5)

我得到了同样的错误。

您应该在
main
之外定义
fib
,而不是在它里面。然后您应该从
main

中删除至少一个
do
do块中定义函数,而没有实际使用任何构造来定义事物(如
let

尝试在块外定义函数:

fib :: (Integral a) => Int -> Int
fib x | x == 0 = 0
      | x == 1 = 1
      | x >= 2 = fib (x - 2) + fib (x - 1)

main = print (fib 5)
如果坚持在本地定义函数(在由
do
块的语句构成的表达式内):


请注意如何使用
let
将新变量
fib
绑定到所需的函数。

您还可以在
do
块外部将
fib
本地定义到
main
。请记住,
Do
是使用各种一元绑定函数的语法糖,因此它内部接受的语法与外部接受的语法并不完全相同。事实上,您的
main
甚至不需要
do
块,因为您只需调用
print
,而不是将任何
IO
操作链接在一起

main = let
         fib x | x == 0 = 0
               | x == 1 = 1
               | x >= 2 = fib (x - 2) + fib (x + 1)
       in
         print (fib 5)
或者您可以使用
where

main = print (fib 5)
       where
         fib x | x == 0 = 0
               | x == 1 = 1
               | x >= 2 = fib (x - 2) + fib (x + 1)
它们是一样的,问题是本地绑定实际上去了哪里
let
。中的
为您提供一个新块,其中新绑定位于作用域中,而
where
使其绑定在其附加的函数的作用域中可用

如果您确实想要一个
do
块,这样您就可以执行多个
IO
操作,您可以将其替换为调用
print
,如下所示:

main = let
         fib x | x == 0 = 0
               | x == 1 = 1
               | x >= 2 = fib (x - 2) + fib (x + 1)
       in
         do print (fib 5)
            print (fib 6)

为什么要将类型签名和函数定义放入do块?我不知道我在做什么。我想说,
do
s不是问题,您可以嵌套它们。但是如果你想在do块中绑定一个变量,你需要使用
let
。当然,但是它们仍然很糟糕和奇怪。我把
fib::(Integral a)=>Int->Int
移到了“main”之外,但是我得到了同样的错误。
main = let
         fib x | x == 0 = 0
               | x == 1 = 1
               | x >= 2 = fib (x - 2) + fib (x + 1)
       in
         do print (fib 5)
            print (fib 6)