我正在阅读 Real World Haskell,试图解决 Ch3, Q10使用 ghc online 。
到目前为止,我有以下代码:
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
尝试编译此代码时收到以下错误(仅发布部分内容,相同的错误多次弹出):
[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
| ^^
我将不胜感激,无论是如何修复我的代码的建议,还是更简洁的解决方案的建议,从三重点确定主导方向。
最佳答案
您可以创建告诉您是右还是左的函数,而不是使用 ==
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)
关于Haskell 长度和滤波器确定直线的凸度或凹度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58187801/