我试图在正确的位置插入一个整数的排序列表。
insert :: Int -> [Int] -> [Int]
insert x [] = [x]
insert x [y:ys] = if x <= y
then [x:y:ys]
else y insert x [ys]
谁能告诉我这里有什么问题以及如何解决?以下是我遇到的错误:
答案 0 :(得分:2)
这里有几个错误。
在参数列表中,y:ys
已经是一个列表,没有必要像[y:ys]
一样再次包装它, - 它的类型为[[Int]]
,即a列表清单。请注意,我们仍然必须在此处放置括号,以告诉Haskell这是一个单独的函数agument:(y:ys)
。
在“then”子句中,x:y:ys
已经是一个列表, - 不要将其包装到[x:y:ys]
。
在“else”子句中,y insert x [ys]
是函数应用程序 - Haskell认为y
是您应用于参数insert
的函数},x
和[ys]
。您需要运营商:
,例如y : insert ...
同样,在您的“else”子句中,您重复第一个错误:ys
已经是一个列表,请不要将其包装到[ys]
。
因此,一个固定的解决方案是:
insert :: Int -> [Int] -> [Int]
insert x [] = [x]
insert x (y:ys) = if x <= y
then x:y:ys
else y : insert x ys
答案 1 :(得分:1)
您将y
视为一种功能,而不是一种元素。您需要使用:
来构建新列表。另外,对于列表,您使用[...]
或 x:xs
,而不是两者。 [x,y]
是x:y:[]
的语法糖。
insert x [] = x
insert x (y:ys) = if x <= y
then x:y:ys
else y : insert x ys
答案 2 :(得分:0)
另一种解决方案,可能不是最有效但仍然应该是好的(没有明确的递归和列表上的模式匹配):
insert :: Int -> [Int] -> [Int]
insert x l = let (lower, greater) = span (< x) l in lower ++ x : greater
这个解决方案也很懒,你可以看到:
λ: insert 3 [1,2,4]
[1,2,3,4]
λ: take 10 $ insert 5 $ repeat 1
[1,1,1,1,1,1,1,1,1,1]