Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 分区可以应用于'a->;我爱你吗?_Haskell_Monads - Fatal编程技术网

Haskell 分区可以应用于'a->;我爱你吗?

Haskell 分区可以应用于'a->;我爱你吗?,haskell,monads,Haskell,Monads,我有以下代码: import System.Directory import System.FilePath import Control.Monad (filterM) filesAndDirs dir = do entries <- getDirectoryContents dir let filtered = [dir </> e | e <- entries, e `notElem` [".", ".."]] files <- filterM

我有以下代码:

import System.Directory
import System.FilePath
import Control.Monad (filterM)

filesAndDirs dir = do
  entries <- getDirectoryContents dir
  let filtered = [dir </> e | e <- entries, e `notElem` [".", ".."]]
  files <- filterM doesFileExist filtered 
  dirs <- filterM doesDirectoryExist filtered 
  return (files, dirs)
导入系统目录
导入System.FilePath
导入控制.Monad(filterM)
filesAndDirs dir=do

条目搜索上的
partitionM
将返回至少两个实现该功能的库。这意味着您可以依赖它们,也可以研究它们的来源

以下是更具可读性的翻译:

您可以使用此功能提升类型的所有功能

(a -> Bool) -> [a] -> ([a], [a])
(即,
分区
中断
span
)到


假设
筛选的
的每个元素都是文件或目录。这不一定是真的。。这可能会有帮助。@melpomene,是的,我没有想到(我只是在查看的位置上有文件和目录)。虽然我对一般情况更感兴趣,但这很好,不一定是System.Directory函数@戴夫,我不是唯一一个想知道的人:)。我不敢相信谷歌搜索在
partitionM
上搜索时没有返回这个。图书馆里似乎没有现成的东西……试着用引号搜索“partitionM”。谢谢。我不知道Hayoo的事我把这个标记为已接受。如果有人设法提升分区(而不是编写一个新的partitionM函数),我可能会更改我的答案,或者解释为什么它不可能。@huynhjl这是可能的,但它太专业化了,本质上需要您编写以下类型签名的提升函数:
((a->Bool)->[a]->([a],[a])->((a->m Bool)->[a]->m([a],[a])
,这并不容易。因此,此功能仅适用于分区
。正因为如此,只实现
partitionM
要明智得多。为什么它只适用于分区,而不适用于返回
([a],[a])
的任何内容,例如
span
splitAt
break
?@huynhjl
splitAt
具有不同的签名。关于
span
break
您是对的,这个提升功能也适用于他们,但就是这样,没有更多的功能了。@huynhjl查看更新。我已经实现了你想要的提升功能。对挑战感兴趣)
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])
(a -> m Bool) -> [a] -> m ([a], [a])