我是Haskell的新手,我想创建一个将两个列表合并在一起的函数,然后将组合列表从最小到最大排序。 这应该在命令行中完成而不使用模块。
这是我目前所拥有的,我无法使“sortList”功能起作用,而且我也不知道如何将这3行合并为1个功能。
let combineList xs ys = xs++ys
let zs = combineList xs ys
let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sortList zs))
答案 0 :(得分:18)
如何在ghci
中对列表进行排序:
Prelude> :m + Data.List
Prelude Data.List> sort [1,4,2,0]
[0,1,2,4]
关于您的职能
let combineList xs ys = xs++ys
为append函数创建另一个别名有什么意义?但如果你真的想要一个 - 它可以定义为let combineList = (++)
。
let zs = combineList xs ys
没有任何意义,因为xs
和ys
在combineList
之外是未知的。
let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sort zs))
此定义无效,因为它不包括空列表情况,(zs:z)
生成无限类型,sort
尚未定义。您可以通过另一种模式匹配获得head
zs
then
。也许你不想在if
声明的{{1}}部分进行另一次递归调用。最后我应该承认这种排序算法根本不起作用。
答案 1 :(得分:4)
在ghci中定义排序函数有点尴尬。我最简单的方法是在文件中编写排序函数,然后将其加载到ghci中。例如,您可以在名为sort.hs
的文件(取自the HaskellWiki)中编写这个简洁(虽然不是就地!)版本的快速排序:
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
并将其加载到ghci:
> :l sort.hs
如果你真的想在ghci中定义函数,你可以这样做(来自the Haskell user's guide):
> :{
> let { quicksort [] = []
> ; quicksort (p:xs) = (quicksort (filter (< p) xs)) ++ [p] ++ (quicksort (filter (>= p) xs))
> }
> :}
一旦定义了这个,你就可以
> let combineAndSort xs ys = quicksort (xs ++ ys)
正如另一个答案已经解释过的那样,从Data.List
导入排序当然会更快,但手动完成这绝对是一个很好的练习。
您的问题表明您对Haskell中的变量范围有点困惑。在这一行
> let combineList xs ys = xs++ys
您引入变量xs
和ys
。在等号的左侧提及它们只意味着combineList
接受两个变量,并且在该函数的主体中,您将这些变量称为xs
和ys
。它不会在函数之外引入名称,所以下一行
> let zs = combineList xs ys
没有意义,因为名称xs
和ys
仅在combineList
范围内有效。要使zs
具有值,您需要给combineList
一些具体的参数,例如:
> let zs = combineList [2,4,6] [1,3,5] --> [2,4,6,1,3,5]
但是由于combineList
的主体是如此简单,实际上更容易做到:
> let zs = [2,4,6] ++ [1,3,5] --> [2,4,6,1,3,5]
最后一行是
> let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sortList zs))
我认为这条线让你很困惑,因为这里有很多不同的错误。 ДМИТРИЙМАЛИКОВ的回答提到了大部分内容,我建议您尝试理解他提到的每个错误。