英文:
How to best handle IO Bool logic?
问题
我经常看到自己使用这个模式:
f x = do
  -- predicate :: a -> IO Bool
  b <- predicate x
  if b then 
    rest ()
  else
    return ()
  where
    rest () = do
      -- 执行剩下的 IO 操作
有其他人使用的去除 if then else 语句的模式吗?你如何最好地处理控制流和 IO Bool?
英文:
I see myself using this pattern a lot:
f x = do
  -- predicate :: a -> IO Bool
  b <- predicate x
  if b then 
    rest ()
  else
    return ()
  where
    rest () = do
      -- rest of my IO operations
is there a pattern other people use to remove the if then else where clauses? How do you best work with control flow and IO Bool?
答案1
得分: 8
f x = do
  b <- predicate x
  when b $ do
    -- 其余的IO操作
英文:
f x = do
  b <- predicate x
  when b $ do
    -- rest of the IO operation
答案2
得分: 2
除了when之外,还有一件方便的事情,与布尔值无关,可以使用-XLambdaCase和一个开放绑定操作符来避免引入变量:
{-# LANGUAGE LambdaCase #-}
f x = do
   predicate >>= \case
     True -> rest ()
     False -> return ()
  where
    rest () = do
      ...
顺便提一下,如果when的参数反转了,那么也可以按照这种方式使用:
thenfore :: m () -> Bool -> m ()
thenfore = flip when
f x = do
   predicate >>= thenfore (rest ())
  where
    rest () = do
      ...
或者,内联rest,
f x = do
   predicate >>= thenfore `id` do
      ...
关于id作为操作符的使用说明:注意id :: a -> a比函数应用操作符($)更一般,所以可以以相同的方式使用它,但它具有更高的优先级,因此可以像上面所示的那样与>>=结合使用。
英文:
In additional to when, another thing that's handy – and not specific to booleans – is to use -XLambdaCase and an open bind operator to avoid having to introduce a variable:
{-# LANGUAGE LambdaCase #-}
f x = do
   predicate >>= \case
     True -> rest ()
     False -> return ()
  where
    rest () = do
      ...
Incidentally, if when had its arguments flipped then this could be used in that style too:
thenfore :: m () -> Bool -> m ()
thenfore = flip when
f x = do
   predicate >>= thenfore (rest ())
  where
    rest () = do
      ...
...or, inlining rest,
f x = do
   predicate >>= thenfore`id`do
      ...
Explanation on the use of id as an operator: notice that id :: a -> a is strictly more general than the function-application operator ($) :: (a -> b) -> (a -> b), so it can be used in the same way, but it has higher precedence and can thus be combined with >>= as done above.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论