Bool类型的排序(即True> False) - 为什么?

时间:2015-11-13 12:23:45

标签: haskell

有人可以解释以下输出吗?

Prelude> compare True False
GT
it :: Ordering
Prelude> compare False True
LT
it :: Ordering

为什么在Haskell中排序Bool类型的值 - 特别是,因为我们可以证明True和False的值不完全是1和0(与许多其他语言不同)?

4 个答案:

答案 0 :(得分:8)

这是Ord的派生实例的工作原理:

data D = A | B | C deriving Ord

鉴于该数据类型,我们得到C > B > A。 Bool被定义为False | True,当您查看其他示例时,它是有意义的,例如:

  • Maybe a = Nothing | Just a
  • Either a b = Left a | Right b

在每个案例中都有"某些" (" truthy")值大于根本没有值(或者"左"或"坏"或" falsy"值)

答案 1 :(得分:5)

虽然Bool不是Int,但它可以转换为0,1的{​​{1}}片段,因为它是Int类型。

Enum

现在,fromEnum False = 0 fromEnum True = 1 可能有所不同,正在推翻Enum0,但对于大多数考虑比特的程序员而言,这可能会令人惊讶。

由于它具有1类型,其他所有内容都相同,因此最好定义遵循相同顺序的Enum实例,以满足

Ord

事实上,从compare x y = compare (fromEnum x) (fromEnum y) 生成的每个实例都遵循这样的属性。

从理论上讲,逻辑学家倾向于将命题从最强到最弱(形成一个格子)。在这种结构中,deriving (Eq, Ord, Enum)(作为命题)是底部,即最小元素,而False是顶部。虽然这只是一个惯例(如果我们选择相反的顺序,理论就会很好),但保持一致是件好事。

次要的缺点:暗示boolean connective实际上True表示p <= q暗示p,而不是像“箭头”似乎表示的那样。

答案 2 :(得分:4)

让我回答一个问题:为什么Ord()个实例?

Bool不同,()只有一个可能的值:()。那你为什么要比较它呢?只有一个值!

基本上,如果所有或大多数标准基本类型都具有公共类的实例,那么它很有用。它可以更轻松地为您自己的类型派生实例。如果Foo没有Ord个实例,并且您的新类型只有一个Foo字段,则您无法自动派生Ord实例

例如,您可能有某种树类型,我们可以在树叶上附加几项信息。像Tree x y z这样的东西。您可能希望有一个Eq实例来比较树。如果Tree () Int String仅仅因为Eq没有()实例,那将会很烦人。这就是为什么()Eq(和Ord以及其他一些人)的原因。

类似的评论适用于Bool。比较两个bool值可能听起来特别有用,但是如果你将Ord实例放在那里就会消失,那将会很烦人。

(另一个复杂因素是有时候我们需要Ord,因为这对事物有逻辑上有意义的排序,有时我们只想要一些任意顺序,通常我们可以使用某些东西作为Data.Map或类似的关键字。可以说应该有两个单独的类......但是没有。)

答案 3 :(得分:0)

基本上,它来自数学。在集合论或类别理论中,布尔函数通常被认为是子集/子对象的分类器。简而言之,函数f :: a -> Bool标识为filter f :: [a] -> [a]。因此,如果我们将一个值从False更改为True,则生成的过滤列表(子集,子对象,等等)将具有更多元素。因此,True被视为&#34;更大&#34;比False