9

我是 Haskell 的新手,我想制作 1 个函数,它需要两个列表然后合并在一起,然后将组合列表从最小到最大排序。这应该在命令行中完成,而不使用模块。

这就是我目前所拥有的,我无法让“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))
4

2 回答 2

28

如何对列表进行排序ghci

Prelude> :m + Data.List
Prelude Data.List> sort [1,4,2,0]
[0,1,2,4]

关于您的功能

let combineList xs ys = xs++ys

为附加函数创建另一个别名有什么意义?但如果你真的想要一个 - 它可以定义为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尚未定义。你可以通过另一个模式匹配来获得headzs也许您不想在语句的then一部分中进行另一个递归调用。if最后我应该承认,这种排序算法根本不起作用。

于 2013-09-29T21:07:39.037 回答
8

在 ghci 中定义排序函数有点尴尬。我认为最简单的方法是将排序函数写入文件中,然后将其加载到 ghci 中。sort.hs例如,您可以在一个名为(取自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 中定义函数,你可以这样做(来自Haskell 用户指南):

> :{
> let { quicksort [] = []
>     ; quicksort (p:xs) = (quicksort (filter (< p) xs)) ++ [p] ++ (quicksort (filter (>= p) xs))
>     }
> :}

一旦定义,你可以做

> let combineAndSort xs ys = quicksort (xs ++ ys)

正如另一个答案已经解释的那样,只导入 sort from 当然会更快 Data.List,但手动执行它绝对是一个很好的练习。

您的问题表明您对 Haskell 中变量的范围有些困惑。在这一行

> let combineList xs ys = xs++ys

你引入变量xsys。在等号左侧提到它们只是意味着combineList需要两个变量,并且在该函数的主体中,您将这些变量称为xsys。它没有在函数之外引入名称,所以下一行

> let zs = combineList xs ys

并没有真正的意义,因为名称xsys仅在 . 范围内有效combineList。为了使zs有一个值,你需要给出combineList一些具体的论据,例如:

> let zs = combineList [2,4,6] [1,3,5]  --> [2,4,6,1,3,5]

但是由于 bodycombineList非常简单,实际上这样做会更容易:

> 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))

我认为这条线让你很困惑,因为这里有很多不同的错误。ДМИТРИЙ МАЛИКОВ 的回答提到了大多数,我鼓励您尝试理解他提到的每个错误。

于 2013-09-29T21:29:09.207 回答