Hayooで検索するとpartitionM
、その機能を実装するライブラリが少なくとも 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])