gpt4 book ai didi

haskell - 删除文件(如果存在)

转载 作者:行者123 更新时间:2023-12-03 09:17:56 25 4
gpt4 key购买 nike

在 Haskell 中这样做的正确方法是什么?

if exists "foo.txt" then delete "foo.txt"
doSomethingElse

到目前为止,我有:
import System.Directory
main = do
filename <- getFileNameSomehow
fileExists <- doesFileExist filename
if fileExists
then removeFile filename
???
doSomethingElse

最佳答案

如果文件不存在,您最好删除文件并简单地恢复:

import Prelude hiding (catch)
import System.Directory
import Control.Exception
import System.IO.Error hiding (catch)

removeIfExists :: FilePath -> IO ()
removeIfExists fileName = removeFile fileName `catch` handleExists
where handleExists e
| isDoesNotExistError e = return ()
| otherwise = throwIO e

这避免了有人在您的代码检查它是否存在并删除它之间删除文件的竞争条件。在您的情况下可能无关紧要,但无论如何这是一种很好的做法。

注意 import Prelude hiding (catch)行 — 这是因为 Prelude 包含来自异常处理的旧函数,现在不赞成使用 Control.Exception,它还有一个名为 catch 的函数;导入行只是隐藏了 Prelude 的 catch赞成 Control.Exception的。

但是,这仍然留下了您更基本的潜在问题:您如何在 IO 中编写条件语句?

好吧,在这种情况下,只需这样做就足够了
when fileExists $ removeFile filename

(使用 Control.Monad.when )。但是在这里查看类型很有帮助,因为它通常在 Haskell 中。

条件的两个分支必须具有相同的类型。所以要填写
if fileExists
then removeFile filename
else ???

我们应该看看 removeFile filename 的类型;随便 ???也就是说,它必须具有相同的类型。

System.Directory.removeFile类型为 FilePath -> IO () , 所以 removeFile filename类型为 IO () .所以我们想要的是一个带有 () 类型结果的 IO 操作。那什么也没做。

嗯, return 的目的|就是构造一个没有效果的 Action ,只返回一个常数值, return ()有正确的类型: IO () (或更一般地说, (Monad m) => m ())。所以 ???return () (你可以看到我在上面的改进片段中使用了它,当 removeFile 因为文件不存在而失败时什么都不做)。

(顺便说一句,您现在应该能够在 when 的帮助下实现 return () ;这真的很简单 :))

如果您一开始很难进入 Haskell 的方式,请不要担心——它会及时自然而然地出现,当它进入时,它会非常有益。 :)

关于haskell - 删除文件(如果存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8502201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com