好吧,我可能做错了,但它让我把头发拉了出来。我找不到任何可以做我想做的事情
拿这个伪代码
my_function left right
= another_function new_left new_right (fourth_function new_left new_right)
where new_left = if some_condition then left else third_function left
new_right = if some_condition then third_function right else right
如何避免重新检查some_condition?我不是在讨论将some_condition
保存为where
构造中的另一个变量。如果我将lets
放入if
我,然后复制in another_function new_left new_right
。
在命令式语言中,我可以做类似
的事情int new_left;
int new_right;
if (condition) {
new_left = left;
new_right = third_function(right);
} else {
new_left = third_function(left);
new_right = right;
}
return another_function(new_left, new_right, fourth_function(new_left, new_right));
我知道在一个函数式语言中你不应该考虑按顺序做事,而应该把它作为表达式的组合,所以我只是想找一种方法来编写原始的伪代码,这样就干了。这似乎是一个简单而相对常见的案例。
修改
很抱歉这个混乱。我无法内联third_function left/right
因为我需要使用它的值两次(更新的伪代码)。 fourth_function
无法移动another_function
答案 0 :(得分:5)
怎么样
my_function left right | somecondition =
another_function left (third_function right)
| otherwise =
another_function (third_function left) right
使用新编辑
my_function left right = ...
where (new_left, new_right) | somecondition = (left, third_function right)
| otherwise = (third_function left, right)
答案 1 :(得分:0)
也许最快捷的方式是
my_function left right
= uncurry another_function $ if some_condition
then (left, third_function right)
else (third_function left, right)
但是jozefg的建议是相当清洁的IMO。
至于更新的问题:当重新使用结果时,实际上将它们命名为变量通常是好的,jozefg再次展示了如何在你的问题中做到这一点。但是(也是为了你的必要事情):Haskell有monad,它可以用于任何命令(当然还有更多)。在您的情况下,Reader
monad,又名函数可以解决问题:
import Control.Monad.Instances
my_function left right =
( uncurry fourth_function >>= flip (uncurry another_function) )
$ if some_condition
then (left, third_function right)
else (third_function left, right)
但这种风格的可读性值得怀疑。
arrows的助手确实有所改善,其中的功能又是一个特例:
import Control.Arrow
my_function = curry $
( uncurry fourth_function >>= flip (uncurry another_function) )
. (if some_condition then second else first) third_function
答案 2 :(得分:0)
如果只使用简单的函数编程,是的,我们可以使用“if”。
如果我们几乎没有“左”,Monads或Monoids(Maybe a
,Either a b
,Any a
,All a
,......)是合适的。:
foo = do
if cond1 then Just smths1 else Nothing
if cond2 then Just smths2 else Nothing
if cond2 then Just smths2 else Nothing
if cond2 then Just smths2 else Nothing
if cond2 then Just smths2 else Nothing
如果我们有很多“左”和“右”,箭头是合适的:
foo = proc (l,r) -> do
nl <- (if cond1 then idA else arr . foo1) -< l
nr <- (if cond2 then arr . foo2 else idA ) -< r
...