我正在编写一个函数,如果满足许多条件,我想返回True。例如,考虑这个比较两个字符串的函数:
test st1 st2
| st1 == st2
| "foo" `isInfixOf` st1 = True
| "baz" `isInfixOf` st2 = True
| otherwise = False
| otherwise = False
显然,这个功能不正确。但是,我正在寻找一种测试几种条件的方法,我想知道:
A)最明智的方法是什么? B)是否有类似于我使用卫兵生成的方法?
为清楚起见,在上面的简单示例中,test
的输出应如下所示:
test "foobuz" "foobuz" = True
test "foobutter" "foobuz" = False
test "buz" "buz" = False
N.B。链接条件可能是一种选择,但在经过两到三次测试后它变得非常难以理解:
test st1 st2 = st1 == st2 && "foo" `isInfixOf` s1 || "baz" `isInfixOf` s2
我在想可能有办法使用Endo Monoid来测试几个条件链?
答案 0 :(得分:6)
if CONDITION then True else False
,可以将其替换为CONDITION
。所以你可以写一下:
main = print (fac 5)
test st1 st2 = st1 == st2 && ("foo" `isInfixOf` st1' || "baz" `isInfixOf` st2)
另一种写这个的方法是:
main = print (fac 5)
test st1 st2
| st1 == st2 && "foo" `isInfixOf` st1 = True
| st1 == st2 && "baz" `isInfixOf` st2 = True
| otherwise = False
答案 1 :(得分:4)
我会使用当地帮手。
test st1 st2
| st1 == st2 = test_after_eq st1 st2
| otherwise = False
where test_after_eq st1' st2'
| "foo" `isInfixOf` st1' = True
| "baz" `isInfixOf` st2' = True
| otherwise = False
我认为这应该有用。
答案 2 :(得分:4)
您可以组合案例表达和模式保护:
test st1 st2 = case st1 == st2 of
True | "foo" `isInfixOf` st1 -> ...
| "baz" `isInfixOf` st2 -> ...
| otherwise -> ...
False -> ...
答案 3 :(得分:4)
您最接近原始代码的方式是使用MultiWayIf
扩展程序:
{-# LANGUAGE MultiWayIf #-}
test st1 st2
| st1 == st2 = ( if
| "foo" `isInfixOf` st1 -> True
| "baz" `isInfixOf` st2 -> True
| otherwise -> False )
| otherwise = False
<小时/> 当然,对于这个特殊的例子,可以通过其他方式更好地完成 - 其他答案已经给出了一些建议,这里还有一个(因为你已经测试了
st1==st2
)
test st1 st2 = st1==st2 && any (`isInfixOf`st1) ["foo", "baz"]
答案 4 :(得分:4)
虽然case
在布尔值上匹配通常有点过分,但它确实为你提供了一个新的上下文。
test st1 st2 = case (st1 == st2) of
True | "foo" `isInfixOf` st1 -> True
| "baz" `isInfixOf` st2 -> True
| otherwise -> False
False -> False
您还可以使用配对形成更具异国情调的基于case
的嵌套if
。
foo a b c = case (p1 a b, p2 b c, p3 a c) of
(True, _ , _ ) -> val1
(False, False, True) -> val2
(False, True , _ ) -> val3
答案 5 :(得分:2)
使用and
和or
:
test st1 st2 = and [ st1 == st2
, or ["foo" `isInfixOf` st1
,"baz" `isInfixOf` st2] ]
使用All
和Any
幺半群:
test' st1 st2 = getAll . foldMap All $
[ st1 == st2
, getAny . foldMap Any $ ["foo" `isInfixOf` st1
,"baz" `isInfixOf` st2]]
来自ala
的{{1}}函数有时可以简化newtypes的换行/解包,但这里并没有为我们节省太多:
Control.Lens.Wrapped