在IO中作用于谓词的惯用Haskell方法是什么?

问题描述 投票:3回答:3

对于某些文件操作,我需要检查文件是否存在,是否已被修改,然后才对其执行一些操作。我的新手Haskell代码如下所示(简化):

someFileOp ::FileContents -> FilePath -> IO (FileOpResult)
someFileOp contents absFilePath = do
    fileExists <- DIR.doesFileExist absFilePath
    if fileExists
        then do
            isMod <- isModified contents absFilePath
            if isMod
                then return FileModified
            else return $ doSomethingWithFile
        else return FileNotFound

确实有效。但是,嵌套的if表达式在我看来错误-不像FP。在IO中检查几个布尔条件然后根据其结果采取某些措施的惯用方式是什么?

haskell conditional-statements predicate io-monad
3个回答
4
投票

您发布的代码对我来说很好。另一种可能性是像ExceptT Err IO这样的短路单子。

data Err = FileNotFound | FileModified

getFileContents :: FilePath -> ExceptT Err IO FileContents
getFileContents fp = do
    exists <- doesFileExist fp
    if exists then {- ... -} else throwError FileNotFound

someFileOp :: FileContents -> FilePath -> ExceptT Err IO FileOpResult
someFileOp fc fp = do
    fc' <- getFileContents fp
    when (fc /= fc') (throwError FileModified)
    doSomethingWithFile

3
投票

忽略丹尼尔(Daniel)在比赛中的要点,以及为什么通常不做检查文件的原因,更多的Haskell解决方案通常是monad转换器。这是ExceptT变压器有意义的典型情况。我还包括对ContT的(误用)用法,以防您好奇并想探索:


3
投票

我将使用whenM :: Monad m => m Bool -> m () -> m()ifM :: Monad m => m Bool -> m a -> m a -> m a,例如在extra中可用:

© www.soinside.com 2019 - 2024. All rights reserved.