Haskell 确定线的凸度或凹度的长度和过滤器
Haskell length and filter to determine convexity or concavity of a line
我正在阅读 Real World Haskell,试图解决 Ch3, Q10 using 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
| ^^
无论是关于如何修复我的代码的建议,还是关于从三重点确定主导方向的更简洁解决方案的建议,我都将不胜感激。
同最近的问题。当你写
length . filter f xs
这被解析为
length . (filter f xs)
这显然是不对的:filter f xs
是一个列表,而不是一个函数,所以用 length
组合它是没有意义的。相反,你可以写
(length . filter f) xs
尽管更流行的拼写方式是
length . filter f $ xs
您可以创建函数来告诉您它是右还是左,而不是使用 ==
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)
我正在阅读 Real World Haskell,试图解决 Ch3, Q10 using 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
| ^^
无论是关于如何修复我的代码的建议,还是关于从三重点确定主导方向的更简洁解决方案的建议,我都将不胜感激。
同最近的问题
length . filter f xs
这被解析为
length . (filter f xs)
这显然是不对的:filter f xs
是一个列表,而不是一个函数,所以用 length
组合它是没有意义的。相反,你可以写
(length . filter f) xs
尽管更流行的拼写方式是
length . filter f $ xs
您可以创建函数来告诉您它是右还是左,而不是使用 ==
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)