探索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)
答案 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