2012-04-15 53 views
2

我有一个Haskell代码的问题,我有以下几点:哈斯克尔条件误差

takeMeHere cs m = 
    |(find (==E) cs == Nothing && (checkNextStep pozxCrt+1 pozyCrt m) == True) = (Just E,[(pozxCrt+1,pozyCrt)] ++ m) 
    |(find (==S) cs == Nothing && (checkNextStep pozxCrt pozyCrt-1 m) == True) = (Just S,[(pozxCrt,pozyCrt-1)] ++ m) 
    |(find (==W) cs == Nothing && (checkNextStep pozxCrt-1 pozyCrt m) == True) = (Just W,[(pozxCrt-1,pozyCrt)] ++ m) 
    |(find (==N) cs == Nothing && (checkNextStep pozxCrt pozyCrt+1 m) == True) = (Just N,[(pozxCrt,pozyCrt+1)] ++ m) 
    |otherwise = (Nothing,m) 
where 
    pozxCrt=fst(head m) 
    pozyCrt=snd(head m) 

checkNextStep x y m = if(find (== (x,y)) m == Nothing) then True 
    else False 

我得到一个parse error on input "|"。如果我用这样的代码编写代码,如果然后...如果那么它工作。但我想使用|为更紧凑的编码。这里似乎有什么问题?

+5

你不需要'== TRUE'不断:如果事情是真实的,然后检查,这是真正的没有按”让它更真实。因为'if'中的条件已经是'Bool',所以你也不需要'if ... then True else False'。 – huon 2012-04-15 11:29:15

回答

7

要修复解析错误,请从第一行删除=。 =号被放在守卫之后。

接下来,你应该缩进“其中”

takeMeHere cs m 
    |(find (==E) cs == Nothing && (checkNextStep pozxCrt+1 pozyCrt m) == True) = (Just E,[(pozxCrt+1,pozyCrt)] ++ m) 
    |(find (==S) cs == Nothing && (checkNextStep pozxCrt pozyCrt-1 m) == True) = (Just S,[(pozxCrt,pozyCrt-1)] ++ m) 
    |(find (==W) cs == Nothing && (checkNextStep pozxCrt-1 pozyCrt m) == True) = (Just W,[(pozxCrt-1,pozyCrt)] ++ m) 
    |(find (==N) cs == Nothing && (checkNextStep pozxCrt pozyCrt+1 m) == True) = (Just N,[(pozxCrt,pozyCrt+1)] ++ m) 
    |otherwise = (Nothing,m) 
    where 
    pozxCrt=fst(head m) 
    pozyCrt=snd(head m) 

这将至少解析,但它不会编译。 (checkNextStep pozxCrt pozyCrt+1 m)应该是(checkNextStep pozxCrt (pozyCrt+1) m)

让我补充一点,你可以解决很多冗长的代码:

  • find (==E) cs == Nothing可以更改为E `notElem` x
  • 你并不需要真正的比较:改变x == Truex
  • if x then True else False能改为x
  • [x]++y可改为x:y
  • 您可以使用模式这样的匹配:(pozxCrt, pozyCrt) = head m(pozxCrt, pozyCrt):_ = m

结果是:

takeMeHere cs m                 
    | E `notElem` cs && checkNextStep (pozxCrt+1) pozyCrt m = (Just E,(pozxCrt+1,pozyCrt):m) 
    | S `notElem` cs && checkNextStep pozxCrt (pozyCrt-1) m = (Just S,(pozxCrt,pozyCrt-1):m) 
    | W `notElem` cs && checkNextStep (pozxCrt-1) pozyCrt m = (Just W,(pozxCrt-1,pozyCrt):m) 
    | N `notElem` cs && checkNextStep pozxCrt (pozyCrt+1) m = (Just N,(pozxCrt,pozyCrt+1):m) 
    | otherwise = (Nothing,m)             
    where                   
    (pozxCrt, pozyCrt) = head m             

checkNextStep x y m = (x,y) `notElem` m 

你有警卫大量的重复。许多重复是创造新功能的标志。

move E (x, y) = (x+1, y) 
move S (x, y) = (x, y-1) 
move N (x, y) = (x, y+1) 
move W (x, y) = (x-1, y) 

takeMeHere cs m 
    | canGo E = go E 
    | canGo S = go S 
    | canGo W = go W 
    | canGo N = go N 
    | otherwise = (Nothing,m) 
    where 
    pos = head m 
    canGo dir = dir `notElem` cs && checkNextStep (move dir pos) m 
    go dir = (Just dir, move dir pos:m) 

checkNextStep (x, y) m = (x,y) `notElem` m 

下一步:使用find canGo [E,S,W,N]摆脱后卫:

takeMeHere cs m =                
    case find canGo [E,S,W,N] of             
     Just dir -> (Just dir, move dir pos:m)          
     Nothing -> (Nothing, m) 
    where ... 
+0

非常感谢,这太好了,我没有使用Haskell中的所有语法,所以我最终编写了一些甚至不起作用的丑陋代码。 – user1272703 2012-04-15 12:37:54

+2

@ user1272703:pleace如果您认为他完全解决了您的问题,请接受sdcwc的回答:) – 2012-04-15 13:05:05

+0

另外,您能否扩展移动和“ - >”语法的含义。警卫重复的主要问题是什么?谢谢 – user1272703 2012-04-16 18:14:41

3

我可以在您的代码中看到至少三个错误。

  • 第一行的=必须删除。在每个|的后卫之后,语法需要=。基本上,错误是说你的第一个管道符号|=之后出乎意料,因为后者在那个位置上没有防护。
  • 当你给它们输入函数时,你应该在数学表达式中放置括号,因为像+这样的中缀运算符在函数应用程序中的优先级较低。​​被评估为(checkNextStep pozxCrt) + (1 pozyCrt m)(这显然是一个错误),而不是checkNextStep (pozxCrt+1) pozyCrt m
  • where应该相对于第一行缩进。

除非你有你省略了代码其他错误,这样它应该工作:

takeMeHere cs m -- no more "=" here 
    |(find (==E) cs == Nothing && (checkNextStep (pozxCrt+1) pozyCrt m) == True) = (Just E,[(pozxCrt+1,pozyCrt)] ++ m) 
    |(find (==S) cs == Nothing && (checkNextStep pozxCrt (pozyCrt-1) m) == True) = (Just S,[(pozxCrt,pozyCrt-1)] ++ m) 
    |(find (==W) cs == Nothing && (checkNextStep (pozxCrt-1) pozyCrt m) == True) = (Just W,[(pozxCrt-1,pozyCrt)] ++ m) 
    |(find (==N) cs == Nothing && (checkNextStep pozxCrt (pozyCrt+1) m) == True) = (Just N,[(pozxCrt,pozyCrt+1)] ++ m) 
    |otherwise = (Nothing,m) 
    where -- indentation 
    pozxCrt=fst(head m) 
    pozyCrt=snd(head m) 

顺便问一下,你的代码是相当多余的,你应该做的事与True所有这些比较(请参阅@ dbaupp对您的问题的评论)。 我建议你学习一点Haskell的运算符优先级和语法,它会帮助你很多让你的代码更易于阅读:)