Haskell相当于Ruby的slice_when

时间:2016-08-27 08:22:59

标签: haskell slice

我是Haskell的新手,我希望一个函数像Ruby的slice_when一样工作:

slice_when红宝石

package

的Haskell

a = [1,2,4,9,10,11,12,15,16,19,20,21]
b = a.slice_when {|i, j| i+1 != j }
p b.to_a #=> [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]

非常感谢。

2 个答案:

答案 0 :(得分:5)

这是一个sliceWhen实现,我相信你想要的工作:

sliceWhen :: (a -> a -> Bool) -> [a] -> [[a]]
sliceWhen _ []  = []
sliceWhen _ [x] = [[x]]
sliceWhen f (x:y:xs)
  | f x y     = [x] : sliceWhen f (y:xs)
  | otherwise = let z:zs = sliceWhen f (y:xs)
                in (x:z) : zs

上面的函数在每个边界上运行提供的谓词,如果它返回True,它会创建一个接缝。否则,它会将“当前”值固定到列表其余部分的第一个元素上。

答案 1 :(得分:3)

没有显式递归,并使用NonEmpty

import Data.List.NonEmpty

sliceWhen :: (a -> a -> Bool) -> [a] -> [NonEmpty a]
sliceWhen p = foldr f []
    where
    f z [] = [z :| []]
    f z gss@(gs@(x :| xs) : xss) = if p z x
                                   then (z :| []) : gss
                                   else cons z gs : xss