dia*_*rov 6 file-extension haskell filepath
我在Haskell相对缺乏经验,我想改进,所以对于我的学习项目,我有以下要求:
.md.toplevel/.excluded..filename.md.swp.我搜遍了所有的SO.这是我到目前为止所拥有的:
import qualified System.FilePath.Find as SFF
import qualified Filesystem.Path.CurrentOS as FP
srcFolderName = "src"
outFolderName = "output"
resFolderName = "res"
ffNotHidden :: SFF.FindClause Bool
ffNotHidden = SFF.fileName SFF./~? ".?*"
ffIsMD :: SFF.FindClause Bool
ffIsMD = SFF.extension SFF.==? ".md" SFF.&&? SFF.fileName SFF./~? ".?*"
findMarkdownSources :: FilePath -> IO [FilePath]
findMarkdownSources filePath = do
paths <- SFF.find ffNotHidden ffIsMD filePath
return paths
Run Code Online (Sandbox Code Playgroud)
这不起作用.在"findMarkdownSources"中进行printf风格的调试,我可以验证filePath是否正确,例如"/home/user/testdata"(打印包含",如果告诉你的话).列表paths总是空的.我绝对肯定目录中有markdown文件我已指定(find/path/to/dir -name"*.md"找到它们).
因此,我有一些具体的问题.
在haskell中有很多方法可以做到这一点.似乎至少有六个包(fileman,system.directory,system.filepath.find)专用于此.这里有一些问题可以回答:
每个人都有三种独特的方式来实现我想要达到的目标,所以,我们差不多有10种方法可以做到......
如果它有帮助,我对基本的haskell相当舒服,但是如果我们开始变得过于沉重的monad和applicative functors你们需要放慢速度(我没有足够使用haskell来保持这种状态).不过,我发现hackage上的haskell文档难以理解.
所以,我们差不多有10种方法可以做到这一点......
这是另一种方法,使用目录,文件路径和额外包中的函数,但不是太多的monad魔法:
import Control.Monad (foldM)
import System.Directory (doesDirectoryExist, listDirectory) -- from "directory"
import System.FilePath ((</>), FilePath) -- from "filepath"
import Control.Monad.Extra (partitionM) -- from the "extra" package
traverseDir :: (FilePath -> Bool) -> (b -> FilePath -> IO b) -> b -> FilePath -> IO b
traverseDir validDir transition =
let go state dirPath =
do names <- listDirectory dirPath
let paths = map (dirPath </>) names
(dirPaths, filePaths) <- partitionM doesDirectoryExist paths
state' <- foldM transition state filePaths -- process current dir
foldM go state' (filter validDir dirPaths) -- process subdirs
in go
Run Code Online (Sandbox Code Playgroud)
这个想法是用户传递一个FilePath -> Bool函数来过滤不需要的目录; 还有一个初始状态b和一个转换函数b -> FilePath -> IO b,它处理文件名,更新b状态并可能有一些副作用.请注意,状态的类型由调用者选择,调用者可能会在那里放置有用的东西.
如果我们只想在生成文件名时打印文件名,我们可以这样做:
traverseDir (\_ -> True) (\() path -> print path) () "/tmp/somedir"
Run Code Online (Sandbox Code Playgroud)
我们正在使用()虚拟状态,因为我们在这里并不需要它.
如果我们想将文件累积到列表中,我们可以这样做:
traverseDir (\_ -> True) (\fs f -> pure (f : fs)) [] "/tmp/somedir"
Run Code Online (Sandbox Code Playgroud)
如果我们想过滤一些文件怎么办?我们需要调整传递给traverseDir它的转换函数,以便忽略它们.
| 归档时间: |
|
| 查看次数: |
633 次 |
| 最近记录: |