Safe Haskell | None |
---|---|
Language | Haskell2010 |
Boring
and Absurd
classes. One approach.
Different approach would be to have
-- none-one-tons semiring data NOT = None | One | Tons type family Cardinality (a :: *) :: NOT class Cardinality a ~ None => Absurd a where ... class Cardinality a ~ One => Boring a where ...
This would make possible to define more instances, e.g.
instance (Mult (Cardinality a) (Cardinality b) ~ None) => Absurd (a, b) where ...
Functions
Function is an exponential:
Cardinality (a -> b) ~ Exponent (Cardinality b) (Cardinality a)
or shortly |a -> b| = |b| ^ |a|
. This gives us possible instances:
|a| = 0 => |a -> b| = m ^ 0 = 1
, i.e.
, orAbsurd
a =>Boring
(a -> b)|b| = 1 => |a -> b| = 1 ^ n = 1
, i.e.
.Boring
b =>Boring
(a -> b)
Both instances are Boring
, but we chose to define the latter.
Note about adding instances
At this moment this module misses a lot of instances, please make a patch to add more. Especially, if the package is already in the transitive dependency closure.
E.g. any possibly empty container f
has Absurd
a => Boring
(f a)
Classes
Boring
types which contains one thing, also
boring
. There is nothing interesting to be gained by
comparing one element of the boring type with another,
because there is nothing to learn about an element of the
boring type by giving it any of your attention.
Boring Law:
boring
== x
Note: This is different class from Default
.
Default
gives you some value,
Boring
gives you an unique value.
Also note, that we cannot have instances for e.g.
Either
, as both
(
and
Boring
a, Absurd
b) => Either a b(
would be valid instances.Absurd
a, Boring
b) => Either a b
Another useful trick, is that you can rewrite computations with
Boring
results, for example foo :: Int -> ()
, if you are sure
that foo
is total.
{-# RULES "less expensive" foo = boring #-}
That's particularly useful with equality :~:
proofs.
Boring () Source # | |
Absurd a => Boring [a] Source # | Recall regular expressions, kleene star of empty regexp is epsilon! |
Absurd a => Boring (Maybe a) Source # |
|
Boring a => Boring (Identity a) Source # | |
Boring b => Boring (a -> b) Source # | |
(Boring a, Boring b) => Boring (a, b) Source # | |
Boring (Proxy * a) Source # | |
(Boring a, Boring b, Boring c) => Boring (a, b, c) Source # | |
Boring a => Boring (Const * a b) Source # | |
(~) * a b => Boring ((:~:) * a b) Source # | Type equality is |
Boring b => Boring (Tagged * a b) Source # | |
(Boring a, Boring b, Boring c, Boring d) => Boring (a, b, c, d) Source # | |
(Boring a, Boring b, Boring c, Boring d, Boring e) => Boring (a, b, c, d, e) Source # | |
More integeresting stuff
boringRep :: (Representable f, Absurd (Rep f)) => f a Source #
If an index of Representable
f
is Absurd
, f a
is Boring
.
untainted :: (Representable f, Boring (Rep f)) => f a -> a Source #
If an index of Representable
f
is Boring
, f
is isomorphic to Identity
.
See also Settable
class in lens
.