我是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]_
这正是我的代码所做的,实际的改组工作正如预期的那样。但正如我所提到的,有一个测试我无法通过我当前的实现。)
因此,其中一项测试是天幕应采取:[3.4, 2.3, 5, 185, 23]
并返回:_[3.4, 5, 23, 2.3, 185]_
。
使用我的代码,我得到:_[3.4, 5.0, 23.0, 2.3, 185.0]_
这是正确的,除了" .0"附加到 5 , 185,和 23 。
为什么会这样?
我怎样才能这样做" 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 = []
答案 0 :(得分:4)
答案是你的代码是正确的。
当列表到达您的函数时,所有元素都已经是相同的类型
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
所以你真正面临的是显示问题。克里斯马丁建议Data.Decimal
,这是一种方法。我的观点是你没有问题,你的代码是正确的,而且是你需要改变的测试用例的处理。
答案 1 :(得分:0)
听起来你想要使用Decimal类型。
λ> import Data.Decimal
λ> [3.4, 5, 23, 2.3, 185] :: [Decimal]
[3.4,5,23,2.3,185]