Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 是否将列表中的连续重复项分组?_List_Haskell - Fatal编程技术网

List 是否将列表中的连续重复项分组?

List 是否将列表中的连续重复项分组?,list,haskell,List,Haskell,非常基本,但我发现这个问题令人沮丧。我正在尝试对列表中的连续元素进行分组: myList = [1,2,3,4,4,4,5] 变成 myList = [[1],[2],[3],[4,4,4],[5]] 这是我尝试将foldr与累加器一起使用: print $ foldr (\ el acc -> if el /= head (head acc) then el ++ (head acc) else acc) [['a']] myList 我不明白为什么会出现以下错误: Couldn'

非常基本,但我发现这个问题令人沮丧。我正在尝试对列表中的连续元素进行分组:

myList = [1,2,3,4,4,4,5]
变成

myList = [[1],[2],[3],[4,4,4],[5]]
这是我尝试将foldr与累加器一起使用:

print $ foldr (\ el acc -> if el /= head (head acc) then el ++ (head acc) else acc) [['a']] myList
我不明白为什么会出现以下错误:

Couldn't match expected type ‘[a0]’ with actual type ‘Int’
In the expression: 'a'
In the expression: ['a']
In the second argument of ‘foldr’, namely ‘[['a']]’

任何建议都很好

使用
foldr
,它应该是:

group :: (Eq a) => [a] -> [[a]]
group = foldr (\x acc -> if head acc == [] || head (head acc) == x then (x:head acc) : tail acc else [x] : acc) [[]]

案例的类型为
[[Char]]
,您正在尝试构建类型为
[[Int]]]
的值。我们的基本情况应该是一个空列表,我们将在每个步骤中添加列表元素

让我们看看接下来编写的匿名函数。请注意,我们将失败,因为类型基于累加器中当前的
if
(它们必须返回与累加器相同类型的值。如果我们对累加器进行模式匹配,并在每种情况下以不同的方式应用函数,则会更好、更干净:

func :: Eq a => [a] -> [[a]]
func = foldr f []
  where f x []        = undefined
        f x (b@(b1:_):bs)
            | x == b1   = undefined
            | otherwise = undefined
当我们遇到基本情况时,我们应该只添加包装在列表中的our元素:

f x [] = [[x]]
接下来,我们将处理非空列表。如果x等于列表头部的下一个头部,我们应该将其添加到该列表中。否则,我们应该

f x (b@(b1:_):bs)
  | == b1   = (x:b):bs
  | = [x]:b:bs
综上所述,我们有:

func :: Eq a => [a] -> [[a]]
func = foldr f []
  where f x []        = [[x]]
        f x (b@(b1:_):bs)
          | x == b1    = (x:b):bs
          | otherwise = [x]:b:bs
解决了这个问题后,使用lambda函数可以更简洁地重写它。请注意,
head
[[]]]
只是
[]
,因此我们可以将空列表情况和相等情况作为一个操作来处理。因此,我们可以重写:

func :: (Eq a) => [a] -> [[a]]
func = foldr (\x (b:bs) -> if b == [] || x == head b then (x:b):bs else [x]:b:bs) [[]]

然而,这个解决方案最终需要使用
head
,因为我们必须对累加器的所有版本进行模式匹配。

编写折叠列表只需要回答两种情况:
[]
(空列表,或“nil”)和
x:xs
(元素后跟列表,或“cons”)

当列表为空时,答案是什么?假设答案也是一个空列表。因此:

nilCase = []
consCase x ggs@(g1@(g11:_):gs)
  | x == g11  = (x:g1):gs
  | otherwise = [x]:ggs
当列表不为空时,答案是什么?这取决于我们已经积累了什么。假设我们已经积累了一个组。我们知道组是非空的

consCase x ((g11:_):gs)
如果
x==g11
,则我们将其添加到组中。否则,我们将开始一个新组。因此:

nilCase = []
consCase x ggs@(g1@(g11:_):gs)
  | x == g11  = (x:g1):gs
  | otherwise = [x]:ggs
如果我们还没有积累任何组呢?那么我们就创建一个新组

consCase x [] = [[x]]
我们可以将这三个案例合并为两个:

consCase x ggs
  | g1@(g11:_):gs <- ggs, x == g11 = (x:g1):gs
  | otherwise                      = [x]:ggs

el++head xs
的类型是
[a]
,但累加器的类型是
[[a]]
。如果
语句是
的话,你就不能返回不同的类型。你不知道吗?我认为第一个不太紧凑的版本更好。它更可读,不会用
(==)测试空列表(这样做会带来一个不必要的
Eq
约束,尽管在这种特定情况下,您无论如何都需要
Eq
),并为空列表提供
[]
而不是
[[]]
,这是一个更自然的结果。在最后一点上:您可能会问哪个元素是
[]
“组”如果所有列表最终都以空列表结束,则对应于
func xs
的最后一个元素是否应始终为
[]
。使用
[]
而不是
[[]]
作为初始累加器可避免此类问题。