Haskell 列表理解:列表中的布尔项用作谓词

Haskell List Comprehension: Boolean Item in List used as predicate

我正在写一个函数majority

函数 returns True 如果至少有两个参数是 True.

函数 returns False 如果至少有两个参数是 False.

函数可以这样写:

majority :: (Bool,Bool,Bool) -> Bool
majority (True,True,_)=True
majority (True,_,True) = True
majority (_,True,True)=True
majority _ = False

或者,可以使用列表理解:

majority' (x,y,z) = length [b | b <- [x,y,z] , b] >= 2

我不完全理解为什么第二种解决方案有效。

我知道这意味着我们将 b 设为 [x,y,z] 之一,而应用于 bb 必须是 True。此列表的长度必须大于或等于 2.

谓词中的b(第三个b)是否改变它的值,因为它等于x,然后是y,然后是z.或者,b 是否始终具有 x 的值?

我试过了:

majority'' (x,y,z) = length [b | b <- [x,y,z] , True] >= 2

我发现这总是 returned True,即使函数应该 return False.

另外,我注意到

[b | b <- [False,True,True] , True] 会 return [False,True,True]

一般来说,

[b | b <- [x,y,z] , True] 会 return [x,y,z]

然而,

[b | b <- [False,True,True] , b] 会 return [True,True]

一般来说,

[b | b <- [x,y,z] , b] 会 return 一个 True 的列表,它与 [x,y,z]

中的 True 的数量一样长

这解释了原因

majority'' (x,y,z) = length [b | b <- [x,y,z] , True] >= 2

总是returns True。不等式总是 True,因为列表 [b | b <- [x,y,z],True] 的长度总是 3.

为什么使用 b 作为谓词有效?

majority' (x,y,z) = length [b | b <- [x,y,z] , b] >= 2

I don't fully understand why this second solution works.

让我们首先关注列表理解:

[b | b <- [x,y,z] , b]

这里我们创建了一个列表 [x, y, z] 并且我们将枚举它,使用 b 作为枚举器。因此,它看起来像 Python 中的 for 循环,例如

下一部分,列表理解右侧的 b 是一个 过滤器。这意味着它只会在 bTrue 时产生结果。这意味着如果 [x, y, z]False, False, True,那么列表理解将产生一个 True,因为过滤器 b 将拒绝前两项,从那时起 bFalse.

因此我们构建了一个 True 的列表:列表中的所有项目都是 True,但我们对列表中的项目不感兴趣。我们对列表理解产生的 number 项感兴趣。因此,我们利用 length :: [a] -> Int 来确定 xyz 的次数是 True。因此,这意味着:

length [b | b <- [x, y, z], b]  -- number of True's in [x, y, z]

如果这个数大于等于2,那么我们就知道至少有两个True