Reputation: 89
I have a problem with a Haskell code, I have the following:
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
I get a parse error on input "|"
. If I write the code with something like if then else if then...it works. But I want to use the | for a more compact coding.What seems to be the problem here ?
Upvotes: 2
Views: 205
Reputation: 25654
To fix parsing error, remove = from first line. The = sign is put after the guards.
Next, you should indent "where"
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)
This will at least parse, yet it won't compile. The (checkNextStep pozxCrt pozyCrt+1 m)
should be (checkNextStep pozxCrt (pozyCrt+1) m)
.
Let me add that you can fix a lot of verbose code:
find (==E) cs == Nothing
can be changed to E `notElem` x
x == True
to x
if x then True else False
can be changed to x
[x]++y
can be changed to x:y
(pozxCrt, pozyCrt) = head m
or (pozxCrt, pozyCrt):_ = m
The result is:
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
You have a lot of repetition in the guards. A lot of repetition is a sign to create new functions.
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
Next step: use find canGo [E,S,W,N]
to get rid of the guards:
takeMeHere cs m =
case find canGo [E,S,W,N] of
Just dir -> (Just dir, move dir pos:m)
Nothing -> (Nothing, m)
where ...
Upvotes: 7
Reputation: 8937
I can see at least three errors in your code.
=
on the first line have to be removed. The syntax requires a =
after the guard of each |
. Basically, the error is saying you that the first pipe symbol |
is unexpected after an =
because the latter, in that position, is used without guards.+
have a lower precedence with respect to function application. checkNextStep pozxCrt+1 pozyCrt m
is evaluated as (checkNextStep pozxCrt) + (1 pozyCrt m)
(which is obviously an error), and not as checkNextStep (pozxCrt+1) pozyCrt m
.where
should be indented with respect to the first line.Unless you have other errors in the code you omitted, this way it should work:
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)
By the way, your code is quite redundant, you should do something about all those comparisons with True
(see @dbaupp's comment on your question).
I suggest you to study a little more Haskell's operator precedence and syntax, It will help you a lot in making your code easier to read :)
Upvotes: 3