首页 > 解决方案 > 有条件地按顺序将函数应用于值

问题描述

如果我有一个值并且我想使用 monad 对其应用多个转换,我可以这样做,

func3 =<< func2 =<< func1 value

但是如果我希望每个函数有条件地执行,这就是我认为可以完成的方式。

applyFuncs value = do
  if condition1
    then value' <- func1 value
    else let value' = value
  if condition2
    then value'' <- func2 value'
    else let value'' = value'
  if condition3
    then value''' <- func3 value''
    else let value''' <- value''
  return value'''

但是,写这个很乏味,所以我在网上寻找了一个解决方案,但不知何故我找不到任何有用的东西。是否有我可以像这样使用的库函数?

when' condition3 func3 =<< when' condition2 func2 =<< when' condition1 func1

标签: haskell

解决方案


所以你有了:

value :: a
f1, f2, f3 :: a -> a
cond1,cond2,cond3 :: a -> Bool

你说你可以用一个单子来做到这一点。为什么不使用单子?

import Control.Monad.Trans.State
whenM f op =
       do s <- f <$> get
          if s then op else pure ()
all3 :: a -> a
all3 val = flip execState val $
    do whenM cond1 $ modify f1
       whenM cond2 $ modify f2
       whenM cond3 $ modify f3

或者不要,只做一两个助手:

all3again :: Int -> Int
all3again val =
    ite cond1 f1 val
    |> ite cond2 f2
    |> ite cond3 f3

ite :: (a -> Bool) -> (a -> a) -> a -> a
ite c a v | c v = a v
          | otherwise = v

(|>) :: a -> (a -> b) -> b
(|>) v f = f v
infixl 5 |>

推荐阅读