我正试图找出完成函数isHullEdge的最佳方法。目前,我正试图使用列表理解来完成这个任务,但是我得到了一个类型错误。我仍然是Haskell的初学者,所以我很难理解堆栈跟踪,找出需要修复的东西。
type Edge a = (Point a, Point a)
-- Given an edge (that determines a line), say whether, as one moves along the
-- edge from its first to its second point, one must turn right (1) or left (-1)
-- to get to the point, or whether the point is on the line itself (0).
lineSide :: Real a => Edge a -> Point a -> a
lineSide ((e1x,e1y),(e2x,e2y)) (px,py) = signum ((px-e1x)*(e2y-e1y) - (e2x-e1x)*(py-e1y))
-- isHullEdge returns true just in case all points are on the same side of or
-- on the line determined by an edge.
isHullEdge :: Real a => [Point a] -> Edge a -> Bool
isHullEdge points edge | length points == 0 = True
| length [x | x <- points, lineSide edge x >= 0 || lineSide edge x <= 0] == length points = True
| otherwise = Falsemod11PA.hs:54:50: error:
* Couldn't match expected type `[t0]' with actual type `a'
`a' is a rigid type variable bound by
the type signature for:
isHullEdge :: forall a. Real a => [Point a] -> Edge a -> Bool
at mod11PA.hs:52:15
* In the expression: lineSide edge x
In a stmt of a list comprehension: c <- lineSide edge x
In the first argument of `(==)', namely
`[c | x <- points, c <- lineSide edge x]'
* Relevant bindings include
x :: Point a (bound at mod11PA.hs:54:32)
edge :: Edge a (bound at mod11PA.hs:53:19)
points :: [Point a] (bound at mod11PA.hs:53:12)
isHullEdge :: [Point a] -> Edge a -> Bool
(bound at mod11PA.hs:53:1)发布于 2017-03-18 02:42:43
您可能指的是length [ c | x <- points, c <- lineSide edge x],而不是[ c | x <- points, c <- lineSide edge x]。一个等于0的列表没有任何意义。附带注意,检查长度是否为零是不好的;这是一个O(n)计算。使用null检查列表是否为空,因为列表是O(1)。
使用all ((>=0) . lineSide edge) points作为您的条件是一个更惯用的解决方案。只有当你真正想要使用列表来做某件事时,你才应该使用列表理解,而不是做这样的测试。请注意,all f xs = foldl (\a x -> if f x then a else False) True xs
https://stackoverflow.com/questions/42869773
复制相似问题