Usted sería mejor eliminar el archivo y simplemente recuperar si no existe:
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
Esto evita la condición de carrera de una persona borrar el archivo entre su código que comprueba si existe y lo elimina. Puede que no importe en su caso, pero de todos modos es una buena práctica.
Observe la línea import Prelude hiding (catch)
- esto se debe a que el Preludio contiene funciones más antiguas del manejo de excepciones que ahora están en desuso en favor de Control.Exception, que también tiene una función llamada catch
; la línea de importación simplemente oculta el Prelude's catch
a favor de Control.Exception.
Sin embargo, eso aún deja su pregunta subyacente más fundamental: ¿cómo se escribe condicional en IO
?
Pues bien, en este caso, bastaría con que se haga
when fileExists $ removeFile filename
(usando Control.Monad.when). Pero es útil aquí, como suele ser en Haskell, mirar los tipos.
Ambas ramas de un condicional deben tener el mismo tipo. Así que rellenar
if fileExists
then removeFile filename
else ???
debemos mirar el tipo de removeFile filename
; cualquiera que sea ???
es, tiene que tener el mismo tipo.
System.Directory.removeFile tiene el tipo FilePath -> IO()
, entonces removeFile filename
tiene el tipo IO()
. Entonces, lo que queremos es una acción IO con un resultado del tipo ()
que no hace nada.
Bueno, el propósito de return
es construir una acción que no tiene efectos, y sólo devuelve un valor constante, y return()
tiene el tipo correcto para esto: IO()
(o más generalmente, (Monad m) => m()
). Por lo tanto, ???
es return()
(que puede ver que usé en mi fragmento mejorado anterior, para no hacer nada cuando removeFile
falla porque el archivo no existe).
(Por cierto, ahora debería ser capaz de implementar when
con la ayuda de return()
, es muy simple :))
No se preocupe si le resulta difícil entrar en el camino de las cosas Haskell al principio, llegará naturalmente a tiempo, y cuando lo haga, será muy gratificante. :)
La función 'doesFileExist' es realmente una invitación a las condiciones de carrera. No debería existir. – augustss
@augustss: ¿Qué tal si cambiamos el nombre a 'didFileExistLastTimeIChecked'? –
Sugiero 'didFileNotNeverExist'. – ehird