haskell - 有条件地按顺序将函数应用于值
问题描述
如果我有一个值并且我想使用 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
解决方案
所以你有了:
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 |>
推荐阅读
- c# - 匿名类型不是匿名的
- java - 快速排序递归堆栈溢出
- python - 如何从匹配的字符串中获取先前的值?
- prolog - Prolog中的离散对数
- amazon-web-services - 是否可以在启用 spark.eventLog.compress 的情况下查看 spark 历史服务器中的日志?
- nginx - 如何在我的示例中编写入口控制器目标重写规则?
- javascript - 自动滚动到页面底部,但用户可以中断滚动
- r - R将xlsx工作簿合并到多标签文件中
- database-migration - Laravel 8 通知主键迁移错误
- javascript - 如何验证赛普拉斯中的错误消息?