In Haskell, is there a way to do IO in a function guard?
For example:
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = retur开发者_Python百科n False
| doesFileExist x == True = return False
| otherwise = return True
Can this be made to work?
You're already in the IO
monad, so why not use the following?
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| otherwise = do exists <- doesFileExist x
return $ not exists
For applicative goodness:
import Control.Applicative
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| otherwise = not <$> doesFileExist x
As you can see, the applicative route is even more concise than the guards you'd like to use in your question!
No, there's no way to do this (short of unsafe tricks which would be completely inappropriate here).
BTW doesFileExist x == True
would be better written as doesFileExist x
were it possible at all.
This works and does what's needed:
newfile :: FilePath -> IO Bool
newfile fn = do
x <- runErrorT $ do
when ((length fn) <= 0) (throwError "Empty filename")
dfe <- liftIO $ doesFileExist fn
when (dfe) (throwError "File already exists")
return True
return $ either (\_ -> False) id x
The type of guard clauses must be Bool
. The type of doesFileExist x
is IO Bool
. The type mismatch means you can't do that.
精彩评论