【问题标题】:How to sort a list in Haskell in command line ghci如何在命令行ghci中对Haskell中的列表进行排序
【发布时间】:2013-09-29 20:31:26
【问题描述】:

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

【问题讨论】:

  • 你需要自己写排序算法吗?如果没有,我建议导入Data.List 并使用sort 函数。然后你可以写成combineAndSort xs ys = sort (xs ++ ys)

标签: list sorting haskell


【解决方案1】:

如何对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

这是没有意义的,因为 xsys 在您的 combineList 之外是未知的。

let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sort zs))

此定义无效,因为它没有覆盖和清空列表大小写,(zs:z) 产生无限类型,sort 尚未定义。你可以通过另一个模式匹配得到headzs。也许你不想在if 语句的then 部分进行另一个递归调用。最后我应该承认,这种排序算法根本不起作用。

【讨论】:

    【解决方案2】:

    在 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
    

    您引入了变量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]
    

    但由于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))
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 2015-11-22
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2018-08-16
      • 2016-05-20
      • 1970-01-01
      相关资源
      最近更新 更多