Haskell长度和过滤器,用于确定直线的凸度或凹度
我正在阅读现实世界的Haskell,试图用ghc解决这个问题 到目前为止,我有以下代码:Haskell长度和过滤器,用于确定直线的凸度或凹度,haskell,lambda,filter,grahams-scan,Haskell,Lambda,Filter,Grahams Scan,我正在阅读现实世界的Haskell,试图用ghc解决这个问题 到目前为止,我有以下代码: 数据方向点=MyLeft点| MyRight点|直线推导(显示) getDirectionFromTriple::方向p->方向p->方向p->方向p->方向p getDirectionFromTriple p1 p2 p3 |(长度过滤器(=MyLeft)[p1,p2,p3])>1=MyLeft p3 |(长度过滤器(=MyRight)[p1,p2,p3])>1=MyRight p3 |否则=直线 我在
数据方向点=MyLeft点| MyRight点|直线推导(显示)
getDirectionFromTriple::方向p->方向p->方向p->方向p->方向p
getDirectionFromTriple p1 p2 p3
|(长度过滤器(=MyLeft)[p1,p2,p3])>1=MyLeft p3
|(长度过滤器(=MyRight)[p1,p2,p3])>1=MyRight 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)
在其他错误中:
p3::Direction p
,MyLeft p3::Direction(Direction p)
,这是错误的类型。旁白:length xs>1
穿过xs
的整个脊椎,因为Int
是严格的;这在这里并不重要,但是如果length xs
预期为大(或无限),那么您可以使用例如not(small xs)
来提高效率,其中small=null。drop 1
以下各项都无法避免上述错误:(length.filter(=MyLeft)$[p1,p2,p3])(length.filter(=MyLeft)[p1,p2,p3])((length.filter(=MyLeft))[p1,p2,p3])(length$filter(=MyLeft)[p1,p2,p3])这些建议修复了第一类错误,但没有修复第二类错误(即(=MyLeft)
本身不是一个很好的函数)。
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)