Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔:检查所有条件是否都为真。如果返回true,则返回false_Haskell_If Statement_Boolean_Multiple Conditions - Fatal编程技术网

Haskell 哈斯克尔:检查所有条件是否都为真。如果返回true,则返回false

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

今天下午我写了一些Haskell,我有一个必须满足的条件清单。如果它们都是真的,我想返回真的,如果其中一个是假的,那么返回假的

我有一个有效的方法,但我只是想知道是否有更好的方法来实现它的可读性/效率

以下是我所拥有的:

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