Haskell说我的卫士有一个分析错误



所以过去几天我一直在玩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块的语句形成的表达式中):

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

请注意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。。in为您提供了一个新的块,其中新的绑定在作用域中,而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)

相关内容

  • 没有找到相关文章

最新更新