使用if else块的Haskell递归函数

时间:2014-08-02 15:44:20

标签: haskell if-statement recursion

您好我是Haskell的新手并且在我的函数doSomething

中收到此错误
  

有条件的意外分号:          if(solveMaze                (x + 1)y ex ey arr wasHere correctPath)然后执行{replaceNth                                                                     correctPath                                                                   ! x y真实;                                                                   return true};别的没什么      也许你打算使用-XDoAndIfThenElse?

我已经查阅了缩进,一切似乎都是正确的。

以下是我的代码

replaceValue n newVal (x:xs)
     | n == 0 = newVal:xs
     | otherwise = x:replaceValue (n-1) newVal xs

doSomething :: Int -> Int -> Int -> Int -> [String] -> [[Bool]] -> [[Bool]] -> Bool
doSomething x y a b arr visited correct = do
 if (x == a && y == b) 
  then do return True   
  else if (arr !! y !! x  == 'A' || visited !! x !! y == True) 
   then do return False  
   else do
    replaceValue visited !! x y True   
    if (x /= 0) 
     then do 
      if(doSomething (x-1) y a b arr visited correct) 
       then do
        replaceValue correct !! x y True
        return True
       else do 
        Nothing   
     else if (x /= length arr !! 0) 
      then do  
       if(doSomething (x+1) y a b arr visited correct) 
        then do
         replaceValue correct !! x y True
         return True
       else Nothing   
     else if (y /= 0) 
      then do 
       if(doSomething x (y-1) a b arr visited correct) 
        then do
         replaceValue correct !! x y True
         return True
        else Nothing   
     else if (y /= length arr) 
      then do
       if (doSomething x (y+1) a b arr visited correct) 
        then do
         replaceValue correct !! x y True
         return True
        else Nothing   
     else Nothing
    return False

谢谢!

1 个答案:

答案 0 :(得分:3)

问题在于代码的这一部分

   if(doSomething (x+1) y a b arr visited correct) 
    then do
     replaceValue correct !! x y True
     return True
   else Nothing

最后else应缩进超过if。一个额外的空间应该足够了。

但是,您的代码有几个问题。您正在使用大量do s,但函数的类型不使用任何monad。我的建议:

  • 您似乎坚持使用在命令式编程中使用的相同代码结构,这通常很难转换为函数式语言。也许你应该先开始学习Haskell做基本练习。 LYAH是一个受欢迎的教程网站。

  • 对于此特定代码,您需要一个Bool s的二维数组。您使用列表列表对其进行建模,但如果您需要随机访问此数组,则会导致性能下降。我会改用vectors,因为它们提供快速随机访问。

  • 我无法清楚地了解您的功能正在尝试执行的功能。如果使用可变向量的有状态程序确实是最自然的选择,我会使用State monad或ST monad来编码。然而,在开始使用monad之前,我强烈建议您深入了解该语言的基础知识。 LYAH仅在第12章和第13章解释了monad,这是正确的。

我建议这样做,因为代码如

do replaceValue .....
   return True

在功能性世界中看起来毫无意义:它似乎试图修改"数组中的某些东西,在非命令式语言中没有意义。如果不使用monad,可以将函数重写为

type Grid = [[Bool]]  -- or vectors...
doSomething :: Int -> Int -> Int -> Int -> [String] -> Grid -> Grid -> (Grid, Bool)

请注意,最终输出不再是Bool,而是一对具有预期修改的Bool和新Grid