Parece que cualquier instancia de Bounded debería tener una implementación sensata de Enum. No puedo pensar personalmente en un contraejemplo, aunque si a alguien se le ocurre uno que no sea patológico, entenderé por qué este no es el caso.
Al hacerlo :i
en las dos clases de tipos, parece que la única excepción actualmente en la biblioteca estándar es para las tuplas, que son limitadas pero no enumeraciones. Sin embargo, cualquier tupla limitada también debe ser enumerable de una manera sensata, simplemente incrementando el último elemento y luego envolviéndolo cuando llegue a maxBound.
Este cambio probablemente también implicaría agregar predB
y / nextB
o algo así a Bounded para una forma segura / en bucle para atravesar los valores de Enum. En este caso toEnum 0 :: (...)
sería igual a(toEnum 0, toEnum 0, ...) :: (...)
Double
/Float
y todos los tipos similares se implementan deEnum
todos modos, solo hacensucc = (+ 1)
yfromEnum = truncate
. El camino de Haskell realmente tiene sentido desde una perspectiva práctica, ya que de lo contrario [0, 0.5 ...] y similares no funcionarían, por lo que parece que a Haskell no le preocupa la contabilidad cuando se trata de Enums.succ
es(+1)
. Eso es extraño, porqueDouble
yFloat
no tiene una precisión infinita y, por lo tanto, son enumerables,succ
podría haberse definido como +1 ULP .Respuestas:
Un ejemplo práctico que me gusta proviene del mundo de los lenguajes de programación: el conjunto de tipos en un sistema OO es limitado y discreto pero no enumerable, y está parcialmente ordenado pero no totalmente ordenado.
El ordenamiento parcial en cuestión es la relación de subtipo
<:
. El límite superior sería el tipo superior (que C # llamaobject
y llama a ScalaAny
), y el límite inferior sería el tipo inferior (ScalaNothing
; C # / Java no tienen equivalente para hablar).Sin embargo, no hay forma de enumerar todos los tipos en el sistema de tipos, por lo que no puede escribir un
instance Enum Type
. Esto debería estar claro: los usuarios pueden escribir sus propios tipos, por lo que no hay forma de saber de antemano qué serán. Puede enumerar todos los tipos en cualquier programa dado, pero no en todo el sistema.Del mismo modo, (de acuerdo con una cierta definición razonable de subtipo),
<:
es reflexivo, transitivo y antisimétrico, pero no total . Hay pares de tipos que no están relacionados por<:
. (Cat
yDog
ambos son subtipos deAnimal
, pero ninguno es subtipo del otro).Supongamos que estamos escribiendo un compilador para un lenguaje OO simple. Aquí está la representación de tipos en nuestro sistema:
Y la definición de la relación de subtipo:
Esto también nos da una relación de supertipaje.
También puede encontrar el límite superior mínimo de dos tipos,
Ejercicio: muestra que
Type
forma un poset completo acotado de dos maneras, debajo<:
y debajo>:
.fuente
x == y = x <= y && y <= x
. Si estuviera diseñando unaPoset
clase, lo habría hechoclass Eq a => Poset a
. Un rápido Google confirma que otras personas han tenido la misma idea .data Bound a = Min | Val a | Max
qué aumenta un tipoa
con+∞
y-∞
elementos. Por construcciónBound a
siempre se puede hacer una instancia de,Bounded
pero solo sería equiparable si el tipo subyacentea
esDouble
, dondeconst (1/0)
esmaxBound
yconst (negate 1/0)
esminBound
pero\x -> 1 - x
y\x -> x - 1
son incomparables.Es porque las operaciones son independientes, por lo que vincularlas con una relación de subclase en realidad no te compra nada. Supongamos que desea crear un tipo personalizado que se implemente
Bounded
, tal vezDoubles
limitado entre un máximo y un mínimo, pero no tuvo necesidad de ninguna de lasEnum
operaciones. SiBounded
fuera una subclase, tendría que implementar todas lasEnum
funciones de todos modos, solo para que se compile.Realmente no importa si hay una implementación razonable
Enum
o cualquier otro número de clases de tipos. Si realmente no lo necesita, no debería verse obligado a implementarlo.Contraste esto con decir,
Ord
yEq
. Allí, lasOrd
operaciones dependen de lasEq
mismas, por lo que tiene sentido exigir a la subclase para evitar la duplicación y garantizar la coherencia.fuente
Bounded
dice "Ord no es una superclase de Bounded ya que los tipos que no están totalmente ordenados también pueden tener límites superior e inferior".<:
para es un subtipo de ,∀ T S. T <: S ∨ S <: T
no se cumple (por ejemplo,int !<: bool ∧ bool !<: int
). Probablemente te encontrarás con esto si estuvieras escribiendo un compilador.