Sorting 在Haskell中对类型a使用排序时出错
我是Haskell的新手,我正在尝试编写一个函数Sorting 在Haskell中对类型a使用排序时出错,sorting,haskell,Sorting,Haskell,我是Haskell的新手,我正在尝试编写一个函数neights::Int->Metric a->Point a->[Point a]->[Point a],这样neights kd p xs根据点列表中的度量d到点p,按距离顺序返回k个最近邻的列表。我的代码是 type Point a = (a, a) type Metric a = Point a -> Point a -> Double type Tuple a = (Double, Point a) create:: Met
neights::Int->Metric a->Point a->[Point a]->[Point a]
,这样neights kd p xs
根据点列表中的度量d到点p,按距离顺序返回k个最近邻的列表。我的代码是
type Point a = (a, a)
type Metric a = Point a -> Point a -> Double
type Tuple a = (Double, Point a)
create:: Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
create d p (x:xs) ys | length xs == 0 = sort(((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
takeP:: Tuple a -> Point a
takeP (_,p) = p
pList:: [Tuple a] ->[Point a]-> [Point a]
pList (x:xs) ys | length xs == 0 = reverse (takeP x : ys)
| otherwise = pList xs (takeP x : ys)
neighbours :: Int -> Metric a -> Point a -> [Point a] -> [Point a]--
neighbours k d p xs = take k (pList (create d p xs []) [])
但我在排序时遇到一个错误,即:
* No instance for (Ord a) arising from a use of `sort'
Possible fix:
add (Ord a) to the context of
the type signature for:
create :: forall a.
Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
* In the expression: sort (((d p x), x) : ys)
In an equation for `create':
create d p (x : xs) ys
| length xs == 0 = sort (((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
起初我使用了类型点a=(Int,Int)
,它工作正常,但在规范中要求该点是类型点a=(a,a)
,这导致了我的错误。另一个问题是,我无法更改函数类型,因此不能按照建议添加(Ord a)
有没有一种方法可以按第一个变量对元组列表进行排序而不会遇到错误?在
create
函数中,可以使用:
create
函数使用了一些反模式,比如使用length
,这需要线性时间。实际上,您可以将其重写为对映射进行排序:
create :: Ord a => Metric a -> Point a -> [Point a] -> [Tuple a]
create d p = sort . map f
where f x = (d p x, x)
由于您在
((dpx),x):ys上排序,因此需要为创建,添加一个类型约束,因此创建::Ord a=>度量a->点a->[点a]->[元组a]->[元组a]
。还要注意长度xs
在这里不是一个好主意,因为它需要线性时间,您可以使用null xs
代替。添加Ord a=>
还需要将其添加到neights
,这将更改所需的函数类型,即neights::Int->Metric a->Point a->[Point a]->[Point a]
感谢您对length xs
的说明,当然,类型约束是可传递的。如果您只想在Double
上排序,您可以使用sortOn fst
来代替。我在create
函数上使用了您的建议,并在必要时添加了Ord a=>
,而且似乎自动测试没有抱怨将Ord a=>
添加到函数类型,并且测试通过了,所以我猜它工作得很好。谢谢你的快速回复。
create :: Ord a => Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
create d p (x:xs) ys | length xs == 0 = sort(((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
create :: Ord a => Metric a -> Point a -> [Point a] -> [Tuple a]
create d p = sort . map f
where f x = (d p x, x)
create :: Metric a -> Point a -> [Point a] -> [Tuple a]
create d p = sortOn fst . map f
where f x = (d p x, x)