partitionM
在Hayoo上搜索将返回至少 2 个实现该功能的库。这意味着您可以依赖它们或研究它们的来源。
这是此实现的更易读的翻译:
partitionM :: (Monad m) => (a -> m Bool) -> [a] -> m ([a], [a])
partitionM p xs = foldM f ([], []) xs
where
f (a, b) x = do
flag <- p x
return $ if flag
then (x : a, b)
else (a, x : b)
关于如何将partition
功能提升到的问题partitionM
,我提出了以下提升功能的实现:
liftSplitter :: (Monad m) =>
((a -> Bool) -> [a] -> ([a], [a])) ->
(a -> m Bool) -> [a] -> m ([a], [a])
liftSplitter splitter kleisliPredicate list = do
predicateResultsAndItems <- sequence $ do
item <- list
return $ do
predicateResult <- kleisliPredicate item
return (predicateResult, item)
return $ results $ predicateResultsAndItems
where
results [] = ([], [])
results ((predicateResult, item) : tail) = (a ++ tailA, b ++ tailB)
where
(a, b) = splitter (const predicateResult) [item]
(tailA, tailB) = results tail
您可以使用此功能解除所有类型的功能
(a -> Bool) -> [a] -> ([a], [a])
(即,partition
和break
)span
到
(a -> m Bool) -> [a] -> m ([a], [a])