【发布时间】:2009-04-25 06:31:03
【问题描述】:
我正在研究Real World Haskell,目前正在做第 3 章末尾的练习。
我正在采用一种不同寻常的方法:尽管我知道他们尚未涵盖的一些语言功能会对我有所帮助,但我正在尝试仅使用 来完成这些练习他们已明确涵盖的内容。 为什么?真的只是为了好玩。感觉就像是在强迫我给我的大脑一些额外的递归练习。
所以我刚刚完成了如下所示的练习:“创建一个函数,根据每个子列表的长度对列表列表进行排序。(您可能需要查看 Data.List 模块中的 sortBy 函数.)"
现在,他们提出了有关 Data.List 模块的提示。但是他们没有说在哪里可以找到参考文档,关于如何导入东西等等。所以我决定滚动我自己的排序,看看我能不能做到。我使用了冒泡排序,因为它是最简单的算法。
结果如下。我想让您的 Haskell 专家对其进行批评...但是 请记住以下警告: 如果您提出改进建议,请根据第 3 章中涵盖的语言特性进行改进真实世界的 Haskell(或者您猜想这些功能可能是什么,而无需费力查找)。我知道有很多很棒的语言特性等着我,它们可以让我把这段代码做得更好,但现在的具体挑战是利用迄今为止所涵盖的“原始”特性来做到这一点。 em>
我确信在某些情况下我会伸手去抓我的肘部,在递归和模式匹配可以为我做更多事情时使用显式控制流的情况等等。我确信代码也可以变得更短、更易读。我敢打赌,有一些我不知道的好习惯可以与我限制自己使用的原始语言功能一起使用。这些是我希望收到的提示。
这可能是任何语言中我引以为豪的最丑陋的代码(至少,我记得)。我的第一次尝试是用一种函数式语言,而不是“Hello, world”类型的东西。现在你要打败它了:)。请温柔一点,但我期待着一些深刻的见解。谢谢。
areListsEqual :: (Eq a) => [a] -> [a] -> Bool
areListsEqual [] [] = True
areListsEqual [] _ = False
areListsEqual _ [] = False
areListsEqual xs ys = (head xs == head ys) && (areListsEqual (tail xs) (tail ys))
charlieSort :: (Eq a) => [[a]] -> [[a]]
charlieSort [] = []
charlieSort (x:xs) | null xs = [x]
charlieSort xs | (length xs) >= 2 = if(not (areListsEqual xs wip))
then charlieSort wip
else wip
where
first = head xs
second = head (tail xs)
theRest = drop 2 xs
swapPairIfNeeded a b = if(length a >= length b)
then [second, first]
else [first, second]
modifiedPair = swapPairIfNeeded first second
wip = (take 1 modifiedPair) ++ charlieSort ( (drop 1 modifiedPair) ++ theRest)
【问题讨论】:
-
有人说这不是问题。我会尽量尊重并持开放态度对待这种观点。但我不得不问,根据什么定义它不是一个问题?您是否有一些我不知道的标准?我正在寻求改进一些代码的建议。这将帮助我在学习语言方面取得进步。是否有某些原因不是有效的 StackOverflow 问题?
-
我认为问题中唯一无效的部分是要求人们根据随机书籍的随机章节限制他们的改进。否则我认为这没什么问题。
-
谢谢,很高兴您同意它是有效的。就限制而言,我只是意味着人们进入 TypeClasses 和列表推导或其他任何东西都是没有意义的。我将阅读本书的其余部分并最终深入了解所有内容,因此我试图将讨论限制在基础知识上。当然,没有人需要查看这本书(我在问题中说过)......只限于基本的语言功能。
-
@apphacker,既然您继续编辑并应用 not-a-question 标签,那么解释一下您的来源如何?这对我来说似乎是一个合理的问题,你不觉得吗?
-
关于“文档在哪里”:最简单的查找方法是使用Hoogle,例如haskell.org/hoogle/?q=sortBy
标签: sorting functional-programming haskell