例如:
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| doesFileExist x == True = return False
| otherwise = return True
这可以工作吗?
您已经在IO
monad 中,那么为什么不使用以下内容呢?
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| otherwise = do exists <- doesFileExist x
return $ not exists
对于应用的好处:
import Control.Applicative
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| otherwise = not <$> doesFileExist x
如您所见,应用路线比您想在问题中使用的守卫更简洁!
不,没有办法做到这一点(缺少不安全的技巧,在这里完全不合适)。
顺便说一句,尽可能doesFileExist x == True
写得更好doesFileExist x
。
这有效并且可以满足需要:
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
保护子句的类型必须是Bool
. 的类型doesFileExist x
是IO Bool
。类型不匹配意味着你不能这样做。