haskell boolean

Entendiendo el Bool de Haskell Derivando un Ord



boolean (3)

Learn You a Haskell presenta el tipo Bool :

data Bool = False | True deriving (Ord)

No entiendo la razón para comparar los de Bool .

> False `compare` True LT > True `compare` False GT

¿Qué se perdería si Bool no se derivara de Ord ?


¡Es porque los diseñadores de Haskell cometieron un error! Nunca vi un libro de texto de matemáticas que mencionara el ordenamiento de los booleanos. Sólo porque pueden ser, no significa con debería. Algunos de nosotros usamos Haskell exactamente porque no nos permite / nos protege de cosas confusas / sin sentido en muchos casos, pero no en este.

instance Ord Bool hace que a => b signifique lo que usted espera que a <= b signifique.

Argumentos anteriores a favor de la instance Ord Bool donde se pueden hacer más tipos comparables implícitamente. Continuando con esa línea de argumentación, algunos podrían querer hacer que todos los tipos sean comparables e incluso tener una tipificación dinámica débil y omitir las clases de tipos por completo. Pero queremos escribir con fuerza exactamente para no permitir lo que obviamente no es correcto, y la instance Ord Bool derrota ese propósito.

En cuanto al argumento de que Bool es un entramado acotado. A diferencia de boolean: = {True, False}, lo que tenemos en Haskell es Bool: = {True, False, bottom} ya no es un enrejado acotado, ya que True y False son elementos de identidad en la presunción de bottom. Eso está relacionado con los comentarios que discuten && vs min, etc.


La instancia de Ord para Bool vuelve mucho más importante cuando necesita comparar valores que contengan Bool algún lugar dentro. Por ejemplo, sin él no podríamos escribir expresiones como:

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

etc.


Bool forma un enrejado acotado * donde False es inferior y True es superior . Esta red limitada define un orden (total) donde False realmente es estrictamente menor que True . (También son los únicos elementos de esta red.)

Las operaciones booleanas and y or también pueden considerarse como reunirse y unirse , respectivamente, en esta red. Meet encuentra el mayor límite inferior y join encuentra el menor límite superior. Esto significa que a && False = False es lo mismo que decir que el límite inferior del fondo y cualquier otra cosa es inferior, y a || True = True a || True = True es lo mismo que decir que el límite superior de arriba y cualquier cosa es superior. Así que cumplir y unirse, que utilizan la propiedad de pedido de los booleanos, son equivalentes a las operaciones booleanas con las que está familiarizado.

Puedes usar min y max para mostrar esto en 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

Esto demuestra que puedes definir && y || solo de la instancia de Ord derivada:

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

Tenga en cuenta que estas definiciones no son equivalentes en presencia de un tipo diferente de fondo porque (&&) y (||) son cortocircuitos (no estrictos en el segundo argumento cuando el primero es False o True , respectivamente), mientras que min y max no son

También, una pequeña corrección: La cláusula deriving no dice que Bool "deriva de" Ord . Le indica a GHC que derive una instancia de la clase de tipos Ord para el tipo Bool .

* Más concretamente, una celosía distributiva complementada . Más específicamente aún, un álgebra booleana .