预期类型"a"与"双精度"错误:哈斯克尔



我正在编写一个程序,根据点列表ps中点p的度量d,按距离顺序返回k个最近邻居的列表。如果列表中的ps少于k个元素,则所有元素都应作为适当的邻居返回。此外,应该根据它们在列表ps中的初始顺序返回两个与p同样接近的点

import Data.List
type Point a = (a,a)
type Metric a = (Point a) -> (Point a) -> Double
nearPoints ::  Int -> Metric a -> Point a -> [Point a] -> [Point a]
nearPoints k d p [] = []
nearPoints k d p ps = take k (sortOn (pointsDistCalc p) ps)
pointsDistCalc :: Metric Double
pointsDistCalc (t1,t1) (t2,t2) = sqrt(((t1-t2)^2)+((t1-t2)^2))

这是错误消息

* Couldn't match type `a' with `Double'
`a' is a rigid type variable bound by
the type signature for:
nearPoints :: forall a.
Int -> Metric a -> Point a -> [Point a] -> [Point a]
Expected type: Point Double
Actual type: Point a
* In the first argument of `pointsDistCalc', namely `p'
In the first argument of `sortOn', namely `(pointsDistCalc p)'
In the second argument of `take', namely
`(sortOn (pointsDistCalc p) ps)'
* Relevant bindings include
ps :: [Point a]
p :: Point a
d :: Metric a
nearPoints :: Int -> Metric a -> Point a -> [Point a] -> [Point a]
11 | nearPoints k d p ps = take k (sortOn (pointsDistCalc p) ps)

有人能帮我拿这个吗

您将pointsDistCalc定义为Point Doubles的Metric,因此这意味着按该距离排序的nearPoints也应该是Point Doubles。

也就是说,签名表明给定了一个度量,因此而不是本身使用PointsDistCalc。因此,您可以使用来实现此功能

nearPoints ::  Int -> Metric a -> Point a -> [Point a] -> [Point a]
nearPoints _ _ _ [] = []
nearPoints kdp0 ps = take k (sortOn (dp0) ps)

这里没有必要将定义分为两种情况:如果给sortOn一个空列表,它将返回一个空的列表:

nearPoints ::  Int -> Metric a -> Point a -> [Point a] -> [Point a]
nearPoints kdp0 ps = take k (sortOn (dp0) ps)

最新更新