list - Haskell:如何从一个公共(public)列表中创建文件列表和目录列表

标签 list file haskell partition io-monad

这是一个新手问题。假设我想把一个文件和目录列表分成一个文件列表和一个目录列表:

getFilesAndDirs :: [FilePath] -> ([FilePath], [FilePath])
getFilesAndDirs paths =
  let ...
  in (dirs, files)

可能这是无可救药的重复,我只是错过了正确的关键字。 执行此操作(和调用)的正确方法是什么?

文件和目录随机出现。

最佳答案

Data.List 包有 partition :: (a -> Bool) -> [a] -> ([a],[a])函数根据谓词将 a 列表拆分为两个 a 列表的元组。

问题是当我们检查文件是否是目录时,我们可能会使用 isDirectory :: FilePath -> IO Bool所以我们不能直接将其用作谓词(因为 IO Bool 不等于 Bool)。

不过,我们可以编写自己的 partitionM,并使用它:

import Data.Bool(bool)
import Data.Foldable(foldrM)

partitionM :: (Foldable t, Monad m) => (a -> m Bool) -> t a -> m ([a], [a])
partitionM p = foldrM (selectM p) ([],[])

selectM :: Monad m => (a -> m Bool) -> a -> ([a], [a]) -> m ([a], [a])
selectM p x (ts,fs) = p x >>= return . bool (ts, x:fs) (x:ts,fs)

然后我们可以像这样使用它:

import System.Directory(isDirectory)

getFilesAndDirs :: [FilePath] -> <b>IO</b> ([FilePath], [FilePath])
getFilesAndDirs = partitionM isDirectory

请注意,它是一个 IO ([FilePath], [FilePath]),因为我们需要执行 I/O 来检查路径是否确实是目录(而不是文件)。

关于list - Haskell:如何从一个公共(public)列表中创建文件列表和目录列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47755054/

相关文章:

haskell - 带有 stateT 的 ForkIO

python - 无法重复迭代 "csv.reader"- 第二次迭代的结果为空

c++ - 如何通过将第一个插入保持在其位置来对我插入列表中的其余元素进行排序?

java - 动态将不可编辑的 JTable 行设置为可编辑

android - 哪个更快? Android 中的 SharedPreference 或文件

java - 下载文件而不知道其大小

java - 从多个推荐列表中提取热门推荐

Java 选项卡 ("\t")无法使用 FileWriter

haskell - 实例替代 IO 的目的是什么?

haskell - 您可以仅使用列表单子(monad)来确定列表的最小值或最大值吗?