11

我经常发现自己编写如下代码:

import System.Directory (doesFileExist)
import Control.Monad (unless)

example = do
  fileExists <- doesFileExist "wombat.txt"
  unless fileExists $ putStrLn "Guess I should create the file, huh?"

也许更好的方法是:

example2 =
  doesFileExist "wombat.txt" >>=
    (\b -> unless b $ putStrLn "Guess I should create the file, huh?")

这里最好的方法是什么?

4

2 回答 2

5

我可以定义一个辅助函数:

unlessM :: Monad m => m Bool -> m () -> m ()
unlessM b s = b >>= (\t -> unless t s)

example3 = unlessM (doesFileExist "wombat.txt") $ 
  putStrLn "Guess I should create the file, huh?"

看起来unlessM会很有用。但事实上我在 Hackage 上没有看到任何类似unlessM(或具有那种类型签名)的东西,这让我认为有一些更好的方法来处理这种情况,我还没有发现。酷孩子们在做什么?

于 2013-04-08T11:40:12.477 回答
5

我已经在flip unless这种情况下使用过,但是这些类型的组合器可能会有点吵。使用该LambdaCase扩展,您至少可以避免为 的结果使用名称doesFileExist,尽管这会导致必须在Trueand上进行模式匹配False,这看起来有点奇怪(取决于您是否认为if不必要)。

{-# LANGUAGE LambdaCase #-}
import System.Directory (doesFileExist)
import Control.Monad (unless)

example' =
  doesFileExist "wombat.txt" >>=
  flip unless (putStrLn "Guess I should create the file, huh?")

example'' =
  doesFileExist "wombat.txt" >>= \ case
    True -> return ()
    False -> putStrLn "Guess I should create the file, huh?"
于 2013-04-08T12:26:51.197 回答