基本的Haskell IO Monad FilePath连接

时间:2014-12-29 12:02:13

标签: haskell monads

探索Haskell IO Monads的基础知识,我想创建一个临时文件的句柄。临时目录FilePath位于IO上下文中,我需要将函数映射到此上下文以使用文件名连接路径。

我的第一次尝试是使用fmap,但是,FilePath以相反的顺序加入。是否可以在不撤销订单的情况下使用fmap?

我的第二次尝试有效,但感觉过于复杂。有什么建议可以改进吗?

哈斯克尔很漂亮。

import System.Directory(getTemporaryDirectory)
import System.FilePath.Posix(joinDrive)

-- fmap is simpler, but the join order was reversed
createTempFile :: FilePath -> IO FilePath
createTempFile filename = fmap (joinDrive filename) getTemporaryDirectory

-- instead, I do this, but it feels overly complicated
createTempFile' :: FilePath -> IO FilePath
createTempFile' filename = getTemporaryDirectory >>= ((\x y -> return (joinDrive y x)) filename)

2 个答案:

答案 0 :(得分:5)

我认为你的问题的答案是使用翻转功能,例如

createTempFile filename = fmap (flip joinDrive filename) getTemporaryDirectory

您还可以使用以下部分:

createTempFile filename = fmap (`joinDrive` filename) getTemporaryDirectory

答案 1 :(得分:5)

您的第一个解决方案会导致反向连接,因为您将filename作为joinDrive的第一个参数传递。这可以扩展为看到结果是正确的:

fmap (joinDrive filename) getTemporaryDirectory

可以改写为:

fmap (\f -> joinDrive filename f) getTemporaryDirectory

这不是你想要的。您需要的是扩展到:

fmap (\f -> joinDrive f filename) getTemporaryDirectory
在Haskell中,你可以使用中缀符号来写这个:

fmap (`joinDrive` filename) getTemporaryDirectory

另外请注意,您应该考虑使用</>而不是joinDrive,因为getTemporaryDirectory不会在结尾处返回带路径分隔符的临时目录:

 import System.Directory(getTemporaryDirectory)
 import System.FilePath.Posix((</>))


 createTempFile :: FilePath -> IO FilePath
 createTempFile filename = fmap (</> filename) getTemporaryDirectory
 -- that expanded is fmap (\f -> f </> filename) getTemporaryDirectory