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

这样可以避免有人在您的代码检查是否存在并删除之前删除该文件的竞争条件。在你的情况下可能并不重要,但反正这是很好的做法。

注意导入Prelude隐藏(catch)行 – 这是因为Prelude包含来自异常处理的较旧的函数,现在已被弃用,有利于Control.Exception,它也有一个名为catch的函数;进口线只是简单地掩盖了前奏曲对Control.Exception的兴趣。

但是,这仍然是您的基本问题:您如何在IO中写入条件?

那么在这种情况下,只需简单地做好就行了

when fileExists $ removeFile filename

(使用Control.Monad.when)。但是,在这里,通常是在Haskell中来查看这些类型是有帮助的。

条件的两个分支必须具有相同的类型。所以填写

if fileExists
    then removeFile filename
    else ???

我们应该看看removeFile文件名的类型;随你 ???是,它必须有相同的类型。

System.Directory.removeFile的类型为FilePath – > IO(),所以removeFile filename具有类型IO()。所以我们想要的是一个IO操作,类型()的结果什么都不做。

那么返回的目的是构造一个没有任何效果的动作,只返回一个常量值,而return()具有这样的正确类型:IO()(或更一般地,(Monad m)=> m ())。那么是return()(您可以看到我在上面的改进的代码段中使用,当removeFile失败,因为该文件不存在)什么都不做。

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

不要担心,如果您发现很难首先进入Haskell的事情,那么它会自然而然地到来,而且如果这样做,这是非常有益的。 🙂

转载注明原文:haskell – 删除文件(如果存在) - 代码日志