Understanding Haskell's Bool Deriving an Ord

前端 未结 3 1385
借酒劲吻你
借酒劲吻你 2021-01-03 19:38

Learn You a Haskell presents the Bool type:

data Bool = False | True deriving (Ord)

I don\'t understand the reason for comparing

相关标签:
3条回答
  • 2021-01-03 19:54

    It is because Haskell designers made a mistake! I never saw a mathematics textbook that mentioned ordering of booleans. Just beacuse they can be it does not mean with should. Some of us use Haskell exactly because it disallows/protects us from confusing/nonsensical things in many cases but not this one.

    instance Ord Bool causes a => b to mean what you expect a <= b to mean!

    Earlier arguments in favour of instance Ord Bool where that you can make more types comparable implicitly. Continuing that line of argument some might want to make every type comparable impicitly and even have weak dynamic typing and omit type classes altogether. But we want strong typing exactly to disallow what is not obviously correct, and instance Ord Bool defeats that purpose.

    As for the argument that Bool is a bounded lattice. Unlike boolean:={True,False}, what we have in Haskell is Bool:={True,False,bottom} is no longer a bounded lattice since neither True nor False are identity elements in the presense of bottom. That is related to those comments discussing && vs min etc.

    0 讨论(0)
  • 2021-01-03 20:16

    The Ord instance for Bool becomes much more important when you need to compare values that contain Bool somewhere inside. For example, without it we wouldn't be able to write expressions like:

    [False,True] `compare` [False,True,False]
    
    (3, False) < (3, True)
    
    data Person = Person { name :: String, member :: Bool } deriving (Eq, Ord)
    

    etc.

    0 讨论(0)
  • 2021-01-03 20:18

    Bool forms a bounded lattice* where False is bottom and True is top. This bounded lattice defines a (total) ordering where False really is strictly less than True. (They are also the only elements of this lattice.)

    The boolean operations and and or can also be looked at as meet and join, respectively, in this lattice. Meet finds the greatest lower bound and join finds the least upper bound. This means that a && False = False is the same thing as saying that the lower bound of bottom and anything else is bottom, and a || True = True is the same thing as saying that the upper bound of top and anything is top. So meet and join, which use the ordering property of the booleans, are equivalent to the boolean operations you are familiar with.

    You can use min and max to show this in Haskell:

    False `min` True = False -- this is the greatest lower bound
    False  &&   True = False -- so is this
    
    False `max` True = True  -- this is the least upper bound
    False  ||   True = True  -- so is this
    

    This shows that you can define && and || just from the derived Ord instance:

    (&&) = min
    (||) = max
    

    Note that these definitions are not equivalent in the presence of a different kind of bottom because (&&) and (||) are short-circuiting (non-strict in the second argument when the first is False or True, respectively) while min and max are not.

    Also, a small correction: The deriving clause does not say thatBool "derives from" Ord. It instructs GHC to derive an instance of the typeclass Ord for the type Bool.

    * More specifically, a complemented distributive lattice. More specifically still, a boolean algebra.

    0 讨论(0)
提交回复
热议问题