Мне нужна была альтернатива filter
, которая вместо того, чтобы отбрасывать ложные случаи, хранит их в отдельном месте. Я придумал ниже, но, к сожалению, он меняет список.Порядок обратного списка без увеличения сложности
Очевидно, я мог бы добавить x в ys или zs вместо cons, но это значительно увеличит сложность.
Есть ли способ сохранить его в порядке, не увеличивая сложность?
splitBy :: (a -> Bool) -> [a] -> ([a],[a])
splitBy f xs = splitBy' f xs ([],[])
where
splitBy' :: (a -> Bool) -> [a] -> ([a],[a]) -> ([a],[a])
splitBy' _ [] result = result
splitBy' f (x:xs) (ys,zs) = if f x then splitBy' f xs (x:ys,zs)
else splitBy' f xs (ys,x:zs)
A [hoogle поиск ] (https://www.haskell.org/hoogle/?hoogle=%28a-%3EBool%29-%3E%5Ba%5D-%3E%28%5Ba%5D%2C%5Ba%5D%29) показывает что эта функция называется 'partition'. –
Спасибо за подсказку, чтобы найти источник и посмотреть, сохраняет ли он их в порядке, не увеличивая сложность. Я новичок в Haskell и не привык искать места, кроме прелюдии. –
[исходный код для 'partition'] (http://hackage.haskell.org/package/base-4.7.0.2/docs/src/Data-List.html#partition): он эффективно добавляет элементы в конец списка, который он строит (оба они). Lazy pattern ('' ') допускает бесконечный список как вход (например,' take 10 $ fst $ partition odd [1 ..] '). –