[英]Haskell function which sorts a list of integer lists according to the length of the sublists
[英]Break a list into sublists of the same length in Haskell
我试图编写一个Haskell代码,该代码接受一个列表并返回一个列表列表。 当我按照以下代码进行操作时,我得到“函数reGroup中的非穷尽模式”
reGroup :: [[Int]] -> [Int] -> [[Int]]
reGroup [[]] [] = [[]]
reGroup [[]] xs = reGroup [(take 3 xs)] (drop 3 xs)
reGroup [[a]] [] = [[a]]
reGroup [[a]] xs = reGroup [[a], (take 3 xs)] (drop 3 xs)
-- calling the reGroup function from another function as follow
reGroup [[]] [1,2,3,4,5,6,7,8,9]
我想要的是[1,2,3,4,5,6,7,8,9]
-> [[1,2,3], [4,5,6], [7,8,9]]
。 我做错了什么,或者有人可以告诉我一种简单的方法?
如果没有累加器(第一个参数),尝试执行此操作可能会更容易。 那我们将有
groupThree :: [a] -> [[a]] --why only work with Ints?
--if the list begins with three elements, stick them in a group
--then group the remainder of the list
groupThree (a:b:c:more) = [a,b,c]:groupThree more
--grouping an empty list gives you an empty list
groupThree [] = []
--if we have some number of elements less than three
--we can just stick them in a list
groupThree other = [other]
或使用拖放
groupThree :: [a] -> [[a]]
groupThree [] = []
groupThree ls = (take 3 ls):groupThree (drop 3 ls)
完全一样的事情。
您的代码不起作用的原因是
reGroup [xs,ls] y
与您的任何情况都不匹配-您只有用于处理第一个参数的代码,该参数是一个元素的列表,该元素是空列表或具有一个元素的列表。
正确使用蓄电池
reGroup back [] = back
reGroup back ls = reGroup (back ++ [take 3 ls]) (drop 3 ls)
不幸的是,这是非常低效的,因为您要追加到列表的末尾(花费时间与该列表的长度成比例...模态惰性)。 相反,您应该使用
reGroup back [] = reverse back
reGroup back ls = reGroup ((take 3 ls):back) (drop 3 ls)
尽管我更喜欢没有累加器的版本,因为它比较懒(因此可以处理无限列表)。
[[a]]
只是一个包含一个元素的列表的列表,例如[[1]]。
所以一次递归后
reGroup [[]] [1,2,3,4,5,6,7,8,9]
至
reGroup [[1,2,3]] [4,5,6,7,8,9]
但是对于这种情况(一个包含3个元素的列表的列表)未定义任何模式。
尝试这个:
reGroup xs n =
if drop n xs == []
then [take n xs]
else [take n xs] ++ (reGroup (drop n xs) n)
可能不是最有效的,但这是一个开始。
它输出:
> reGroup [1..9]
[[1,2,3],[4,5,6],[7,8,9]]
> reGroup [1..10]
[[1,2,3],[4,5,6],[7,8,9],[10]]
出现该错误的原因是,您没有涵盖该功能可以匹配的所有模式。 尝试为基本情况输入_
或两个。
对此稍作更改
reGroup :: [[Int]] -> [Int] -> [[Int]];
reGroup [[]] [] = [];
reGroup a [] = a;
reGroup [[]] xs = reGroup [(take 3 xs)] (drop 3 xs);
reGroup a xs = a ++ reGroup [(take 3 xs)] (drop 3 xs);
做这份工作。
take3 :: [a] -> [[a]]
take3 [] = []
take3 (x:[]) = [[x]]
take3 (x:y:[]) = [[x,y]]
take3 (x:y:z:xs) = [[x,y,z]] ++ take3 xs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.