Data.Bottom
- Package
- purescript-higher-order
- Repository
- matthew-hilty/purescript-higher-order
#Bottom Source
class Bottom (a :: Type) whereThe Bottom typeclass registers partially ordered types that have
a least element or lower boundary.
Because the notion of minimality entails the notion of comparability,
the semantics of an instance of Bottom must be consistent with the
definitional requirements of a partial order. In fact, most instances
of Bottom are also instances of PartialOrd (and likely Ord as well).
In such cases, when a type a is both a registered instance of Bottom
and one of PartialOrd, it must satisfy the following law:
- minimality:
x >=? bottom == Just true
Likewise, if a is an instance of Bottom and also an instance of Ord,
it must satisfy the following analogous law:
- minimality:
x >= bottom
However, although the semantics of Bottom-registered types must be
consistent with the laws of partial ordering, a PartialOrd registration
may not be possible or suitable for all Bottom instances. The
implementation details of the datatype may preclude an instance
declaration. Alternatively, the properties of the type may make such an
instance declaration impractical.
For example, many container-like datatype operators support a total order
(therefore, also a partial order) when they act on total orders.
Array Int, for instance, is a total order because Int is a total
order. However, the bottom element of such container types is generally
independent of the type argument of the container's type constructor. The
bottom element of Array a, for instance, is [] whether a is Int,
String, any other Ord instance, or, conceivably, any other type at
all. That is to say, Array a, for any unconstrained a, satisfies
Bottom. Were a PartialOrd registration a prerequisite of Bottom-
instance declarations, some choice of PartialOrd implementation
satisfiable by Array a for all a would be necessary. Such an
implementation might be the following:
-- # 1
instance partialOrdArray :: PartialOrd (Array a) where
pCompare x y
| null x, null y -> Just EQ
| null x -> Just LT
| null y -> Just GT
| otherwise -> Nothing
This choice is, however, rather coarse for likely uses of partially
orderable arrays. Arrays often contain values of types satisfying Ord,
and a better PartialOrd definition for these kinds of arrays might be
the following:
-- # 2
instance partialOrdArray :: Ord a => PartialOrd (Array a) where
pCompare x y = Just $ compare x y
The existence of two reasonable PartialOrd definitions for Array a
suggests that preferring more-granular definitions whenever possible,
while using #1 above as a backup implementation would be a useful general
strategy. Instance chaining is the standard technique in PureScript to
effect this kind of typeclass-instance contingency. However, the current
strategy of instance resolution by the PureScript compiler rules out
instance chaining in cases like this. Because both declarations in the
would-be chain (see below) share the same head (namely, Array), the
second definition (the backup definition) would not be checked or attempted.
instance partialOrdArray :: Ord a => PartialOrd (Array a) where
pCompare x y = Just $ compare x y
else instance partialOrdArray :: PartialOrd (Array a) where
pCompare x y
| null x, null y -> Just EQ
| null x -> Just LT
| null y -> Just GT
| otherwise -> Nothing
Therefore, to make Bottom registrations of unconstrained Array a and
other similar types possible, without also mandating compiler-ignored (and
possibly idle) PartialOrd definitions, the Bottom typeclass does not
declare PartialOrd as a prerequisite superclass.
Members
bottom :: a
Instances
(Bottom b) => Bottom (a -> b)Bottom (Map k v)Bottom StringBottom (Array a)Bottom (CatList a)Bottom (CatQueue a)Bottom (First a)Bottom (Last a)Bottom (List a)Bottom (Maybe a)Bottom (Set a)Bottom (ZipList a)(Bottom a) => Bottom (Either a b)(Bottom a) => Bottom (EitherR a b)(Semiring a) => Bottom (Additive a)(Semiring a) => Bottom (Multiplicative a)(HeytingAlgebra a) => Bottom (Conj a)(HeytingAlgebra a) => Bottom (Disj a)(Bounded a) => Bottom a