Haskell:根据条件将列表细分为更小的组

Haskell: subdividing a list into smaller groups based on a condition

当我们给函数一个条件和一个列表时,它应该将元素分组到一个列表中,直到一个不满足条件。然后它应该创建一个新的子列表,直到再次满足条件,依此类推。

示例:

切片甚至 [1,3,2,4,5,7,4,6​​] == [[],[1,3],[2,4],[5,7],[4 ,6]]

slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice a (x:y:xs)
  | (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
  | a x == True && a y == False = [x] : [y : slice a xs]
  | a x == False && a y == True = [x] : [y : slice a xs]

当我尝试编译您的代码时,出现错误:

main.hs:4:80: error:
    * Occurs check: cannot construct the infinite type: a ~ [a]
      Expected type: [a]
        Actual type: [[a]]
    * In the second argument of `(:)', namely `slice a xs'
      In the second argument of `(:)', namely `y : slice a xs'
      In the expression: (x : y : slice a xs)
    * Relevant bindings include
        xs :: [a] (bound at main.hs:3:14)
        y :: a (bound at main.hs:3:12)
        x :: a (bound at main.hs:3:10)
        a :: a -> Bool (bound at main.hs:3:7)
        slice :: (a -> Bool) -> [a] -> [[a]] (bound at main.hs:2:1)
  |
4 |   | (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
  |                                                                                ^^^^^^^^^^
exit status 1

例如,您不能执行4:[[6]]。所以我创建了一个允许这样做的函数myadd :: a -> [[a]] -> [[a]]
为了消除更多错误,我使用了对运算符 : 的透彻了解。 第一次启动尝试后,我被迫添加了一个额外的退出规则:slice _ [y] = [[y]].

你设计和修改的结果函数没有return想要的结果。 有必要将其修改为 return 所需的输出。

slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice _ [y] = [[y]]
slice a (x:y:xs)
  | (a x == True && a y == True) || (a x == False && a y == False) = myadd x (slice a (y:xs))
  | a x == True && a y == False = [x] : slice a (y:xs)
  | a x == False && a y == True = [x] : slice a (y:xs)

输出:

[[1,3],[2,4],[5,7],[4,6]]

我会按如下方式解决任务:

slice :: (a -> Bool) -> [a] -> [[a]]
slice a b = slice' a b False

slice' :: (a -> Bool) -> [a] -> Bool -> [[a]]
slice' _ [] _ = [[]]
slice' a (x:xs) b
 | a x == b = []:(slice' a (x:xs) (not b))
 | otherwise = myadd x (slice' a xs b)

输入:

[1,3,2,4,5,7,4,6]

输出:

[[],[1,3],[2,4],[5,7],[4,6]]

附录:

myadd a (x:xs) = (a:x):xs