如何映射和连接FilePath?

时间:2015-04-24 03:05:33

标签: haskell monads io-monad

我还在弄清楚Haskell,尤其是IO monad。

我有一个目录路径列表,例如,

["/some/path", "/another/path", "/yet/another/path", "/still/more"]

我希望将此列表映射到每个路径的完全限定内容列表(不包含...),如下所示:

["/some/path/file.1", "/some/path/somedir", "/some/path/file.2", "/another/path/file.a", "/another/path/a/directory", "/another/path/file.b", "/still/more/file.alpha", ...]

我想我可以用某种双重图来做到这一点,如下:

pathItems <- mapM (\pd -> MapM (\contents -> (pd </>) contents) (getDirectoryContents pd) pathDirs

但这不起作用。我得到的错误是:

program.hs:27:56:
    Couldn't match type `[]' with `IO'
    Expected type: IO Char
      Actual type: FilePath
    In the expression: (pd </>) contents
    In the first argument of `mapM', namely
      `(\ contents -> (pd ) contents)'

program.hs:27:84:
    Couldn't match expected type `[FilePath]'
                with actual type `IO [FilePath]'
    In the second argument of `mapM', namely
      `(getDirectoryContents pathDir)'
    In the expression:
      mapM
        (\ contents -> (pd </>) contents)
        (getDirectoryContents pd)

1 个答案:

答案 0 :(得分:2)

可能的解决方案(导入System.IO System.Directory System.FilePath Control.Applicative):

concat <$> mapM (\pd -> map (pd </>) <$> getDirectoryContents pd) pathDirs
                                   -- ^ this is to work under IO (..)
                    --  ^ this is to affect what's under IO [..]
        -- ^ this returns IO [[FilePath]]

可能有某种方法可以进一步简化它。