【问题标题】:Haskell - Shuffling a list with different types?Haskell - 用不同类型的列表洗牌?
【发布时间】:2017-09-03 06:08:10
【问题描述】:

我对 Haskell 很陌生,几天前我开始学习 Haskell,因为我有一门课程。在这门课程中,有一个作业或家庭作业,我现在被困住了。我希望得到对我的问题的提示和解释,而不是完整、直接的答案,因为这是家庭作业,因此我不想因他人的工作而受到赞扬。

作业是写一个洗牌函数(skyffla)。实际的改组不是我需要帮助理解的,而是算法应该通过的测试之一。我将用括号将算法标记到改组部分,以表示它不太重要。

(skyffla 通过获取第一个元素、第三个元素、第五个元素等等,直到获取所有奇数索引,然后将它们附加到列表中。

第一个列表中的其余元素随后应通过相同的方法处理,并附加到第一个处理的列表中。继续,直到只剩下一个元素,然后最后将其附加到列表中。

例如,如果我输入:

skyffla [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

它会给我:

1: _[1, 3, 5, 7, 9, 11] ++ skyffla ([2, 4, 6, 8, 10, 12])_
2: _[1, 3, 5, 7, 9, 11] ++ [2, 6, 10] ++ skyffla ([4, 8, 12])_
3: _[1, 3, 5, 7, 9, 11, 2, 6, 10] ++ [4, 12] ++ skyffla([8])_ 
(4): _[1, 3, 5, 7, 9, 11, 2, 6, 10, 4, 12, 8]_

这正是我的代码所做的,并且实际的改组正在按预期工作。但正如我所提到的,我目前的实现无法通过一项测试。)

因此,其中一项测试是 skyffla 应该接受:[3.4, 2.3, 5, 185, 23] 并返回:_[3.4, 5, 23, 2.3, 185]_

使用我拥有的代码,我得到:_[3.4, 5.0, 23.0, 2.3, 185.0]_

这是正确的,除了附加到 5185、23 的“.0”。

这是为什么?

我怎样才能让例如“5.0”被列为“5”?

我的代码如下:

skyffla :: [a] -> [a]
skyffla [] = []
skyffla xs
    | length xs == 1 = xs
    | otherwise = dropUnevenElements xs ++ skyffla newList  where
    newList = takeUnevenElements xs

dropUnevenElements :: [a] -> [a]
dropUnevenElements [] = []
dropUnevenElements (x:y:xs) = x:dropUnevenElements xs
dropUnevenElements x = x


takeUnevenElements :: [a] -> [a]
takeUnevenElements [] = []
takeUnevenElements (x:y:xs) = y:takeUnevenElements xs 
takeUnevenElements x = []

【问题讨论】:

  • dropUnevenElements x = x?
  • 而且列表只能包含一种元素。
  • “skyffla”是“shuffle”的一些奇怪的语音翻译吗?它应该真的像“布兰达”。
  • 您不能拥有元素类型不同的列表。测试如何表达?
  • 问题标题并没有真正反映内容。此外,除非将输出验证为作为字符串(这听起来很糟糕),否则.0 根本无关紧要。编写示例输出的人可能根本没有考虑 show 如何适用于 Haskell 中的大多数浮点类型。

标签: haskell


【解决方案1】:

答案是你的代码是正确的。

当列表到达你的函数时,所有元素已经是相同的类型

ghci> [3.4, 2.3, 5, 185, 23]
[3.4,2.3,5.0,185.0,23.0]

因为 Haskell 中的所有列表从一开始都是同质的。 (这里5 被解释为fromInteger 5,它将其转换为上下文所需的任何类型)

如果您将输出作为字符串进行比较,那么您将遇到此问题。如果您将它们作为数字列表进行测试,那不是问题。

ghci> skyffla [3.4, 2.3, 5, 185, 23] == [3.4, 5, 23, 2.3, 185]
True

所以你真正面临的是一个显示问题。 Chris Martin 建议 Data.Decimal,这是一种方法。我的观点是你没有问题,你的代码是正确的,而你对测试用例的处理需要改变。

【讨论】:

    【解决方案2】:

    听起来您想使用Decimal 类型。

    λ> import Data.Decimal
    
    λ> [3.4, 5, 23, 2.3, 185] :: [Decimal]
    [3.4,5,23,2.3,185]
    

    【讨论】:

    • 添加另一个依赖项只是为了摆脱尾随的.0?
    • 为了避免添加依赖项而不适合使用浮点数?哎呀
    • 您可以用其他方式格式化数字。而且由于这是一个具有(可能)严格限制的家庭作业问题,因此甚至可能不允许这样做。
    • 不是想成为一个混蛋,但就目前而言,您的回答并没有完全解决问题。
    • 由于 OP 声明这是家庭作业,我怀疑这是预期的解决方案。
    猜你喜欢
    • 2013-11-26
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 2019-08-26
    • 1970-01-01
    相关资源
    最近更新 更多