2016-07-01 8 views
0

後にアクションを実行するとIO Boolテストのリストを実行して、私はその機能を持っている場合BoolのいずれかがFalseハスケル:単一故障

であれば最後にアクションを実行するための最良の方法は何ですか指定したファイルがディレクトリに存在するかどうかを確認し

check :: FilePath -> IO() 
check s = do 
      r <- doesFileExist s 
      putStrLn s ++ if r then " exists" else " does not exist" 
私は、ファイルのリストをチェックして、すべてのテストに合格した場合に応じて、最後に別の機能を実行できるようにしたいと思います

?これは、常にすべてのテストを実行します

import Control.Monad 

check :: FilePath -> IO Bool 
check = undefined 

process files = do 
    allok <- foldM (\b f -> fmap (b &&) (check f)) True files 
    if allok then putStrLn "All OK" else putStrLn "Oops" 

注:私は私はこのようなfoldMを使用することになり

allPassed = do 
      l <- mapM doesFileExist [`list of files`] 
      if all (==True) l then "all ok" else "meh" 
+0

だから、 'allM'機能、ALL''のモナドと同等のようなものを探していますか? –

+2

私のお勧め:気にしないでください。あなたがファイルを使ってやりたいことを行い、存在しなければ例外をキャッチしてください。結局のところ、このチェックの実行と次のステップの実行との間に存在しなくなる可能性があるため、堅牢なプログラムが必要な場合は、例外を処理する必要があります。 –

+1

OPのアプリケーションはわかりませんが、「明白な」理由で失敗することがないように、高価で時間のかかる作業に着手する前に「飛行前チェック」を実行することが望ましい場合があります。 – ErikR

答えて

1

ようなもので、別途再チェックを行うと考えることができます現時点では

docs for allMは、それが短絡であると言うので、

do allok <- allM check files 
    if allok then ... else ... 

は、最初の障害発生後のチェックの実行を停止します。ここで

更新

は、いくつかのデモコードです:

import Control.Monad 

check :: Int -> IO Bool 
check x = do putStrLn ("x = " ++ show x) 
       return $ even x 

process files = do 
    allok <- foldM (\b f -> fmap (b &&) (check f)) True files 
    if allok then putStrLn "All OK" else putStrLn "Oops" 

main = do process [1..5] -- will print "Oops" 
      process [2,4,6] -- will print "All OK" 
+0

私の 'check'関数は' IO Bool'を返します。それは私が持っている問題です。実際に 'check'を使って各ファイルのコンソールに何かを出力し、最後に最後の出力をしたい渡されるすべてのファイルに依存します。 – matthias

+0

回答が更新されました。 – ErikR

+0

これは実際に私が必要とするものに対して完全に機能します。加えて、私は「allM」で苦労してしまった。素晴らしい答えとあなたの時間をありがとう! #折りたたみとスキャンのために手軽に手に入る! – matthias

1

私はControl.Monad.LoopsパッケージからallMを使用することをお勧めします。値のいずれかがfalseであることがわかると、早期終了します。これは、検査に高価な計算が含まれる場合に便利です。ここで

は簡単な例です:

import Control.Monad.Loops 

doesFileExist :: FilePath -> IO Bool 
doesFileExist path 
    | path == "holiday.jpg" = return True 
    | path == "me.jpg" = return True 
    | path == "pop song.mp3" = return True 
    | otherwise = return False 

check :: FilePath -> IO Bool 
check s = do 
    r <- doesFileExist s 

    putStrLn $ s ++ if r 
         then " exists" 
         else " does not exist" 

    return r 

main :: IO() 
main = do 
    allPassed <- allM check ["holiday.jpg", "cat.mp4", "me.jpg"] 

    if allPassed 
     then putStrLn "Yes" 
     else putStrLn "No" 
関連する問題