将一元表达式输入除非或何时

时间:2021-01-25 17:02:56

I often find myself writing code that looks like this:

我经常发现自己写的代码是这样的:

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

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

Perhaps a better way is:

也许更好的办法是:

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

What's the best approach here?

这里最好的方法是什么?

2 个解决方案

#1


5  

I could define a helper function:

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

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?"

It seems like unlessM would be very useful. But the fact that I don't see anything like unlessM (or with that type signature) on Hackage makes me think that there's some better way to handle this situation, one that I haven't discovered yet. What do the cool kids do?

似乎unlessM会非常有用。但事实是,我在Hackage上看不到unlessM(或那种类型的签名)这样的东西,这使我认为有更好的方法来处理这种情况,我还没有发现这种情况。酷孩子们做什么?

#2


5  

I have made use of flip unless for such cases, but these types of combinators can get a little bit noisy. With the LambdaCase extension, you could at least avoid using a name for the result of doesFileExist, though it would result in having to pattern match on True and False, which can look a little strange (depending on if you believe if is unnecessary or not).

我用过flip除非在这种情况下,但是这些类型的组合器可能会有一点噪音。使用LambdaCase扩展,您至少可以避免使用dofileexist结果的名称,尽管它会导致必须对True和False进行模式匹配,这看起来有点奇怪(取决于您是否相信这是不必要的)。

{-# 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?"

#1


5  

I could define a helper function:

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

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?"

It seems like unlessM would be very useful. But the fact that I don't see anything like unlessM (or with that type signature) on Hackage makes me think that there's some better way to handle this situation, one that I haven't discovered yet. What do the cool kids do?

似乎unlessM会非常有用。但事实是,我在Hackage上看不到unlessM(或那种类型的签名)这样的东西,这使我认为有更好的方法来处理这种情况,我还没有发现这种情况。酷孩子们做什么?

#2


5  

I have made use of flip unless for such cases, but these types of combinators can get a little bit noisy. With the LambdaCase extension, you could at least avoid using a name for the result of doesFileExist, though it would result in having to pattern match on True and False, which can look a little strange (depending on if you believe if is unnecessary or not).

我用过flip除非在这种情况下,但是这些类型的组合器可能会有一点噪音。使用LambdaCase扩展,您至少可以避免使用dofileexist结果的名称,尽管它会导致必须对True和False进行模式匹配,这看起来有点奇怪(取决于您是否相信这是不必要的)。

{-# 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?"