2013-03-07 50 views
0

我正在尝试编写一个Haskell代码,它接受一个列表并返回列表。当我这样做,如下面的代码,我得到“的功能重组非详尽模式”在Haskell中将相同长度的子列表打破列表

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]]。我做错了什么或有人能告诉我一个简单的方法?

回答

7

在没有累加器(第一个参数)的情况下尝试这样做可能更容易。然后,我们将有

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) 

不幸的是,这是非常低效的,因为要附加到列表的末尾(以时间比例到该列表的长度...模lazieness )。相反,你应该使用

reGroup back [] = reverse back 
reGroup back ls = reGroup ((take 3 ls):back) (drop 3 ls) 

虽然我不喜欢的累加器的版本更好,因为它是懒惰(因此可以处理无穷的列表)。

+0

+1尼斯使用模式匹配 – 2013-03-07 22:23:11

+2

的(我认为你有1太多的括号层在'[其他]'。) – huon 2013-03-07 22:28:19

+0

@dbaupp现在固定。 – 2013-03-07 23:13:42

2

试试这个:

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]] 

而且你得到这个错误的原因是因为你还没有覆盖所有的功能可以匹配的模式。尝试投掷一个_或两个为您的基本情况。

4
[[a]] 

只是用一种元素的列表列表,如[[1]]。

所以一个递归后,你从

reGroup [[]] [1,2,3,4,5,6,7,8,9] 

reGroup [[1,2,3]] [4,5,6,7,8,9] 

但这种情况下(与3个元素的列表清单)是没有定义的模式。

1

改变你的代码一点点这个

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); 

做这项工作。

0
take3 :: [a] -> [[a]] 
take3 [] = [] 
take3 (x:[]) = [[x]] 
take3 (x:y:[]) = [[x,y]] 
take3 (x:y:z:xs) = [[x,y,z]] ++ take3 xs 
相关问题