Haskell 哈斯克尔:检查所有条件是否都为真。如果返回true,则返回false
今天下午我写了一些Haskell,我有一个必须满足的条件清单。如果它们都是真的,我想返回真的,如果其中一个是假的,那么返回假的 我有一个有效的方法,但我只是想知道是否有更好的方法来实现它的可读性/效率 以下是我所拥有的:Haskell 哈斯克尔:检查所有条件是否都为真。如果返回true,则返回false,haskell,if-statement,boolean,multiple-conditions,Haskell,If Statement,Boolean,Multiple Conditions,今天下午我写了一些Haskell,我有一个必须满足的条件清单。如果它们都是真的,我想返回真的,如果其中一个是假的,那么返回假的 我有一个有效的方法,但我只是想知道是否有更好的方法来实现它的可读性/效率 以下是我所拥有的: checkMatch :: Person -> Person -> Bool checkMatch seeker candidate | gender candidate == preferedGender seeker && g
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate
| gender candidate == preferedGender seeker
&& gender seeker == preferedGender candidate
&& minAcceptableAge seeker <= age candidate
&& maxAcceptableAge seeker >= age candidate
&& minAcceptableAge candidate <= age seeker
&& maxAcceptableAge candidate >= age seeker = True
| otherwise = False
所以我只是把&&&|和&|对齐,让它看起来更好一点,但我觉得必须有更好的方法,但在搜索谷歌时似乎找不到任何东西
提前感谢 您可能会失去防护装置,并使用
和检查您的状况:
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate = and [
gender candidate == preferedGender seeker
, gender seeker == preferedGender candidate
, minAcceptableAge seeker <= age candidate
, maxAcceptableAge seeker >= age candidate
, minAcceptableAge candidate <= age seeker
, maxAcceptableAge candidate >= age seeker
]
checkMatch::Person->Person->Bool
选中匹配搜索者候选项=和[
性别候选人==优先搜索者
,性别寻求者==优先考虑的候选人
,minAcceptableAge seeker=年龄候选人
,minAcceptableAge候选者=年龄寻求者
]
首先,您可以使用,
简单地保护条件
接下来,我应该将minacage=age
模式重构为一个专用函数,比如
acceptsAge :: Person -> Age -> Bool
judge `acceptsAge` age
= age >= minAcceptableAge judge && age <= maxAcceptableAge judge
那么我就到此为止,这两个首选边的检查不能减少很多。你问的是风格问题,所以没有正确或错误的答案。然而,这里有一些建议
首先,您正在编写此模式的等效项:
isTrue value | value == True = True
| otherwise = False
这当然可以简化为:
isTrue value = value
其次,当您检查多个测试时,您可以使用和
函数作为列表元素通过测试。如果所有元素均为True
,则返回True
,否则将短路并返回False
将这两个想法结合起来,我们得到:
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate
= and [gender candidate == preferedGender seeker,
gender seeker == preferedGender candidate,
minAcceptableAge seeker <= age candidate,
maxAcceptableAge seeker >= age candidate,
minAcceptableAge candidate <= age seeker,
maxAcceptableAge candidate >= age seeker]
checkMatch::Person->Person->Bool
搜索者候选人
=和[性别候选人==优先搜索者,
性别寻求者==优先选择的候选人,
minAcceptableAge搜索者=年龄候选人,
minAcceptableAge候选者=年龄寻求者]
…我可能会这样写 你可以滥用maybe monad作为语法糖:
a |==| b = guard $ a == b
a |>=| b = guard $ a >= b
a |<=| b = guard $ a <= b
a |/=| b = guard $ a /= b
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate = Just () == do
gender candidate |==| preferedGender seeker
gender seeker |==| preferedGender candidate
minAcceptableAge seeker |<=| age candidate
maxAcceptableAge seeker |>=| age candidate
minAcceptableAge candidate |<=| age seeker
maxAcceptableAge candidate |>=| age seeker
a |=| b=guard$a==b
a |>=| b=守卫$a>=b
阿布尔
checkMatch-seeker-candidate=Just()==do
性别候选人|==|更喜欢寻的者
性别寻求者|=|优先考虑的候选人
minAcceptableAge搜索者|=|年龄候选人
minAcceptableAge候选人|=|年龄寻求者
我注意到您的代码包含一些重复项,因为您在两个方向上都检查了所有内容。我将定义一个helper函数checkAcceptable
,它只检查一个方向,然后调用该函数两次:
checkAcceptable :: Person -> Person -> Bool
checkAcceptable seeker candidate =
gender candidate == preferedGender seeker &&
minAcceptableAge seeker <= age candidate &&
maxAccetableAge seeker >= age candidate
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate =
checkAcceptable seeker candidate &&
checkAcceptable candidate seeker
checkAcceptable::Person->Person->Bool
检查可接受的导引头候选者=
性别候选人==优先搜索者&&
minAcceptableAge搜索者=年龄候选人
选中匹配::个人->个人->布尔
搜索者候选人=
检查可接受的导引头候选者&&
检查可接受的候选搜索者
为了最小化代码,您可以这样编写
inRange x (a,b) = a <= x && x <= b
checkOneWay a b = gender b == preferredGender a
&& age b `inRange` (minAcceptableAge a, maxAcceptableAge a)
checkMatch candidate seeker = checkOneWay candidate seeker
&& checkOneWay seeker candidate
inRange x(a,b)=a棒极了,我想我可以用所有的,但不知道id。谢谢!)您不需要id
。使用和::[Bool]->Bool
,它也在前奏曲中。@visi0n你也可以使用all(=True)
,但是all id
做同样的事情。@visi0n你可能也喜欢。顺便说一句。我想我更喜欢使用和而不是警卫,但我喜欢acceptsAge函数。我把它放在的where
块中。谢谢你得到了一个很好的解决方案there@JustinL. 是的,我的想象力消失了。你也许可以使用某种assert
DSL
checkAcceptable :: Person -> Person -> Bool
checkAcceptable seeker candidate =
gender candidate == preferedGender seeker &&
minAcceptableAge seeker <= age candidate &&
maxAccetableAge seeker >= age candidate
checkMatch :: Person -> Person -> Bool
checkMatch seeker candidate =
checkAcceptable seeker candidate &&
checkAcceptable candidate seeker
inRange x (a,b) = a <= x && x <= b
checkOneWay a b = gender b == preferredGender a
&& age b `inRange` (minAcceptableAge a, maxAcceptableAge a)
checkMatch candidate seeker = checkOneWay candidate seeker
&& checkOneWay seeker candidate