I am reading Real World Haskell, trying to solve Ch3, Q10 using ghc online.
So far I have the following code:
data Direction point = MyLeft point | MyRight point | Straight deriving (Show)
getDirectionFromTriple :: Direction p -> Direction p -> Direction p -> Direction p
getDirectionFromTriple p1 p2 p3
| (length . filter (== MyLeft) [p1, p2, p3]) > 1 = MyLeft p3
| (length . filter (== MyRight) [p1, p2, p3]) > 1 = MyRight p3
| otherwise = Straight
I receive the following error when trying to compile this code (only parts posted, the same error pops up several times) :
[1 of 1] Compiling Main ( jdoodle.hs, jdoodle.o )
jdoodle.hs:17:15: error:
* Couldn't match expected type `a0 -> t0 a1'
with actual type `[point0 -> Direction point0]'
* Possible cause: `filter' is applied to too many arguments
In the second argument of `(.)', namely
`filter (== MyLeft) [p1, p2, p3]'
In the first argument of `(>)', namely
`(length . filter (== MyLeft) [p1, p2, p3])'
In the expression: (length . filter (== MyLeft) [p1, p2, p3]) > 2
|
17 | | (length . filter (== MyLeft) [p1, p2, p3]) > 2 = MyLeft p3
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
jdoodle.hs:17:35: error:
* Couldn't match expected type `point0 -> Direction point0'
with actual type `Direction p'
* In the expression: p1
In the second argument of `filter', namely `[p1, p2, p3]'
In the second argument of `(.)', namely
`filter (== MyLeft) [p1, p2, p3]'
* Relevant bindings include
p3 :: Direction p (bound at jdoodle.hs:16:30)
p2 :: Direction p (bound at jdoodle.hs:16:27)
p1 :: Direction p (bound at jdoodle.hs:16:24)
getDirectionFromTriple :: Direction p
-> Direction p -> Direction p -> Direction p
(bound at jdoodle.hs:16:1)
|
17 | | (length . filter (== MyLeft) [p1, p2, p3]) > 2 = MyLeft p3
| ^^
jdoodle.hs:17:39: error:
* Couldn't match expected type `point0 -> Direction point0'
with actual type `Direction p'
* In the expression: p2
In the second argument of `filter', namely `[p1, p2, p3]'
In the second argument of `(.)', namely
`filter (== MyLeft) [p1, p2, p3]'
* Relevant bindings include
p3 :: Direction p (bound at jdoodle.hs:16:30)
p2 :: Direction p (bound at jdoodle.hs:16:27)
p1 :: Direction p (bound at jdoodle.hs:16:24)
getDirectionFromTriple :: Direction p
-> Direction p -> Direction p -> Direction p
(bound at jdoodle.hs:16:1)
|
17 | | (length . filter (== MyLeft) [p1, p2, p3]) > 2 = MyLeft p3
| ^^
I would appreciate either suggestions how to fix my code or suggestions for more succint solutions determining the dominant direction from a triple of points.
You can create functions that tells you if it is right or left instead of using ==
import Data.List
data Direction point = MyLeft point | MyRight point | Straight deriving (Show)
getDirectionFromTriple :: Direction p -> Direction p -> Direction p -> Direction p
getDirectionFromTriple p1 p2 p3
| isDirection isLeft [p1, p2, p3] = MyLeft (getValue p3)
| isDirection isRight [p1, p2, p3] = MyRight (getValue p3)
| otherwise = Straight
isDirection :: (Direction p -> Bool) -> [Direction p] -> Bool
isDirection f ps = (length . filter f) ps > 1
getValue (MyLeft a) = a
getValue (MyRight a) = a
getValue Straight = error "No value in Straight"
isLeft (MyLeft _) = True
isLeft _ = False
isRight (MyRight _) = True
isRight _ = False
main = do
putStrLn $ show $ getDirectionFromTriple (MyRight 2) Straight (MyLeft 1)
putStrLn $ show $ getDirectionFromTriple (MyRight 2) (MyRight 3) (MyLeft 1)
putStrLn $ show $ getDirectionFromTriple (MyLeft 1) (MyLeft 1) (MyRight 2)