开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜