我想检查上一个if condition
的条件,以确定是否要执行下一个if condition
。每个if condition
都可以返回一个值。
编辑:对不起,我之前提供的示例看起来有点奇怪...... :( 这是我的真实示例,我想简化{strong> goToMove 的<{1}}
if-then-else
编辑:错误的例子 当这个东西用java编写时,我可能会使用一个可变的布尔标志,并返回一个可变数据。
goingToMove p routes points w h =
if canMove p points
-- the point can be moved in the map
then let r = routes ++ [p]
l = remainList p points
in move p r l w h
-- the point cannot be moved in the maps
else []
move p routes points w h =
if (length routes) == 2
then routes
else let one = goingToMove (tallRightCorner p) routes points w h in
if (null one)
then let two = goingToMove(tallRightBCorner p) routes points w h in
if (null two)
then let three = goingToMove (tallLeftBCorner p ) routes points w h in
if (null three)
then ....
...... -- until, let eight = ..
else three
else two
else one
但是在Haskell中,没有可变数据,只有public String move (int number){
// base case
if (number == 0){
return "Finished the recursion";
}
// general case
else {
String result;
boolean isNull = false;
if ((result = move(3)) == null){
isNull = true;
}
else {
return result;
}
// continue to execute the if-conditions if the previous condition failed
if (isNull){
if((result = move(2)) == null){
isNull = true;
}
else {
return result;
}
}
if (isNull){
if((result = move(1)) == null){
isNull = true;
}
else {
return result;
}
}
return null;
}
}
条件。然后代码看起来像这样,我想简化这个,因为在我的实际工作中,那里是if-then-else
的8级,看起来很糟糕...... [/ p>
if-then-else
答案 0 :(得分:16)
在Java中如果我想要执行以下操作:
result = func1(arg);
if (result == null){
result = func2(arg);
if (result == null){
result = func3(arg);
if (result == null){
result = func4(arg);
}
}
}
return result;
我实际上在做的是从func1(args)
,func2(args)
,func3(args)
,func4(args)
中找到返回非空的第一个结果。
在Haskell中,我将func1
,func2
,func3
和func4
建模为返回Maybe a
值的函数,以便它们可以如果失败则返回Nothing
。
func1, func2, func3, func4 :: Int -> Maybe Result
然后我可以使用<|>
运算符(来自Control.Applicative
),该运算符具有Maybe a
的以下定义:
Nothing <|> x = x
x <|> _ = x
所以我可以将上面的Java转换为
func1 arg <|> func2 arg <|> func3 arg <|> func4 arg
由于懒惰评估的奇迹,func2 arg
仅在func1 arg
返回Nothing
时进行评估,与Java示例相同。
答案 1 :(得分:1)
编辑:以下是新示例的一些代码:
move p routes points w h
| length routes == 2 = routes
| otherwise = find (not . null) . map gtm [tallRightCorner, tallRightBCorner, tallLeftBCorner]
where gtm f = goingToMove (f p) routes points w h
请注意,这会返回一个可能。您可以使用fromMaybe
来保留默认情况。
这是第一个提出的示例中的旧(但是类型检查)代码
move 0 = "Finished the recursion"
move n = concat . maybeToList . msum $ map move' [3,2,1]
where move' x = let mx = move x in if null mx then Nothing else Just mx
答案 2 :(得分:1)
如果routes
的长度为2,或者goingToMove
的一系列应用中的第一个非空结果因p
应用了哪个角功能,则需要move p routes points w h
| length routes == 2 = routes
| otherwise = head
$ filter (not . null)
$ map tryMove corners
where tryMove f = goingToMove (f p) routes points w h
corners = [ tallRightCorner
, tallRightBCorner
, tallLeftBCorner
-- et cetera
]
。
{{1}}
答案 3 :(得分:0)
没有Maybe的选项可能是为递归添加一个标志(在下面的示例中,您将调用函数并将标志设置为1):
移动p路线点数1
move p routes points w h flag
| (length routes) == 2 = routes
| otherwise =
if null result then move p routes points w h (flag+1)
else result
where result = case flag of
1 -> goingToMove (tallRightCorner p) routes points w h
2 -> goingToMove (tallRightBCorner p) routes points w h
3 -> goingToMove (tallLeftBCorner p) routes points w h
--...etc.
_ -> []