你需要一个稍微复杂一点的累加器:
data Sign = Neg | Zero | Pos
signGroup :: [Integer] -> [[Integer]]
signGroup xs = case
foldr
(\x (sign, ps, ns, ys) ->
-- x - current element
-- sign - sign of the prev. group
-- ps - positive numbers in the current group
-- ns - negative numbers in the current group
-- ys - final list
if x >= 0
then case sign of
Neg -> (Pos, x : ps, [], ns : ys)
Zero -> (Pos, x : ps, [], ys)
Pos -> (Pos, x : ps, [], ys)
else case sign of
Neg -> (Neg, [], x : ns, ys)
Zero -> (Neg, [], x : ns, ys)
Pos -> (Neg, [], x : ns, ps : ys))
(Zero, [], [], [])
xs
of
(_, [], [], ys) -> ys
(_, [], ns, ys) -> ns : ys
(_, ps, [], ys) -> ps : ys
(_, ps, ns, ys) -> ps : ns : ys -- <- unreachable
-- signGroup [1,2,3,-1,-2,-3,1,2,3]
-- => [[1,2,3],[-1,-2,-3],[1,2,3]]