Copyright | (c) 2024 Eitan Chatav |
---|---|
License | MIT |
Maintainer | eitan.chatav@gmail.com |
Stability | experimental |
Portability | non-portable (GHC extensions) |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Data.Default.Singletons
Description
This module defines an Opt
ional type with
either a Def
ault promoted value,
or Some
specific demoted value.
>>>
definite (Def :: Opt True)
True>>>
definite (Some False :: Opt True)
False>>>
definite (Some True :: Opt True)
True>>>
maybe "def" show (perhaps (Def :: Opt True))
"def">>>
maybe "def" show (perhaps (Some True :: Opt True))
"True">>>
maybe "def" show (perhaps (Some False :: Opt True))
"False"
Promoted datakinds and their Demote
d datatypes include:
>>>
:kind! Demote Symbol
Demote Symbol :: * = Text>>>
:kind! Demote Natural
Demote Natural :: * = Natural>>>
:kind! Demote Char
Demote Char :: * = Char>>>
:kind! Demote Bool
Demote Bool :: * = Bool>>>
:kind! Demote [k]
Demote [k] :: * = [Demote k]>>>
:kind! Demote String
Demote String :: * = [Char]>>>
:kind! Demote (Either k j)
Demote (Either k j) :: * = Either (Demote k) (Demote j)>>>
:kind! Demote (k,j)
Demote (k,j) :: * = (Demote k, Demote j)
Because there is no promoted Integer
and Rational
datakinds,
this module defines them as Z
and Q
.
>>>
:kind! Demote Z
Demote Z :: * = Integer>>>
:kind! Demote Q
Demote Q :: * = Ratio Integer
The Opt
type comes with
Num
, Integral
, Fractional
, and Real
instances,
using definite
values to do arithmetic;
and IsString
and IsList
instances,
which let you use literals to construct Opt
.
>>>
"text" :: Opt ("hello" :: Symbol)
Some "text">>>
"string" :: Opt (['a','b','c'] :: String)
Some "string">>>
[1, 2] :: Opt ('[] :: [Natural])
Some [1,2]>>>
Def + 0 :: Opt (Pos 1 :: Z)
Some 1>>>
0.5 + Def :: Opt (Neg 1 :% 3 :: Q)
Some (1 % 6)
Synopsis
- data Opt (def :: k) where
- type SingDef (def :: k) = (SingI def, SingKind k)
- optionally :: SingDef def => Maybe (Demote k) -> Opt (def :: k)
- definite :: forall k def. Opt (def :: k) -> Demote k
- perhaps :: Alternative m => Opt (def :: k) -> m (Demote k)
- demote :: forall {k} (a :: k). (SingKind k, SingI a) => Demote k
- data Z
- type family Neg n where ...
- data Q = (:%) Z Natural
- data SInteger (n :: Z) where
- SPos :: SNat n -> SInteger (Pos n)
- SNegOneMinus :: SNat n -> SInteger (NegOneMinus n)
- data SRational (n :: Q) where
Documentation
Optional Datatype
data Opt (def :: k) where Source #
Opt
ional type with
either a Def
ault promoted value def
,
or Some
specific Demote
d value.
Opt
is a Monoid
which yields the leftmost Some
.
>>>
mempty :: Opt "xyz"
Def>>>
Def <> "abc" <> "qrs" :: Opt "xyz"
Some "abc"
You can use Opt
as an optional function argument.
>>>
let greet (name :: Opt "Anon") = "Welcome, " <> definite name <> "."
>>>
greet "Sarah"
"Welcome, Sarah.">>>
greet Def
"Welcome, Anon."
Or, you can use Opt
as an optional field in your record type.
>>>
:{
data Person = Person { name :: Text , age :: Natural , alive :: Opt (True :: Bool) } :}>>>
let isAlive person = definite (alive person)
>>>
let jim = Person {name = "Jim", age = 40, alive = Def}
>>>
isAlive jim
True
Instances
(SingDef def, IsString (Demote k)) => IsString (Opt def) Source # | |
Defined in Data.Default.Singletons Methods fromString :: String -> Opt def # | |
SingDef def => Monoid (Opt def) Source # | |
Semigroup (Opt def) Source # | |
(SingDef def, IsList (Demote k)) => IsList (Opt def) Source # | |
(SingDef def, Num (Demote k)) => Num (Opt def) Source # | |
(SingDef def, Read (Demote k)) => Read (Opt def) Source # | |
(SingDef def, Fractional (Demote k)) => Fractional (Opt def) Source # | |
(SingDef def, Show (Demote k)) => Show (Opt def) Source # | |
SingDef def => Default (Opt def) Source # | |
Defined in Data.Default.Singletons | |
(SingDef def, Eq (Demote k)) => Eq (Opt def) Source # | |
(SingDef def, Ord (Demote k)) => Ord (Opt def) Source # | |
Defined in Data.Default.Singletons | |
type Item (Opt def) Source # | |
Defined in Data.Default.Singletons |
perhaps :: Alternative m => Opt (def :: k) -> m (Demote k) Source #
Deconstructs an Opt
to an Alternative
Demote
d value.
Def
maps to empty
,
and Some
maps to pure
,
inverting optionally
.
demote :: forall {k} (a :: k). (SingKind k, SingI a) => Demote k #
A convenience function that takes a type as input and demotes it to its
value-level counterpart as output. This uses SingKind
and SingI
behind
the scenes, so
.demote
= fromSing
sing
This function is intended to be used with TypeApplications
. For example:
>>>
demote @True
True
>>>
demote @(Nothing :: Maybe Ordering)
Nothing
>>>
demote @(Just EQ)
Just EQ
>>>
demote @'(True,EQ)
(True,EQ)
Promoted Datakinds
Datakind Z
, promoting Integer
,
>>>
:kind! Demote Z
Demote Z :: * = Integer
with Pos
for constructing nonnegative integer types,
and Neg
for constructing nonpositive integer types.
>>>
demote @(Pos 90210)
90210>>>
demote @(Neg 5)
-5>>>
demote @(Neg 0)
0>>>
demote @(Pos 0)
0
Constructors
Pos Natural | |
NegOneMinus Natural |
Instances
Enum Z Source # | |
Num Z Source # | |
Read Z Source # | |
Integral Z Source # | |
Real Z Source # | |
Defined in Data.Default.Singletons Methods toRational :: Z -> Rational # | |
Show Z Source # | |
Eq Z Source # | |
Ord Z Source # | |
SingKind Z Source # | |
KnownNat n => SingI ('NegOneMinus n :: Z) Source # | |
Defined in Data.Default.Singletons Methods sing :: Sing ('NegOneMinus n) # | |
KnownNat n => SingI ('Pos n :: Z) Source # | |
Defined in Data.Default.Singletons | |
type Demote Z Source # | |
Defined in Data.Default.Singletons | |
type Sing Source # | |
Defined in Data.Default.Singletons |
type family Neg n where ... Source #
Type family for negating a Natural
.
Equations
Neg 0 = Pos 0 | |
Neg n = NegOneMinus (n - 1) |
Datakind Q
, promoting Rational
,
>>>
:kind! Demote Q
Demote Q :: * = Ratio Integer
with :%
for constructing rational types.
>>>
demote @(Pos 7 :% 11)
7 % 11>>>
demote @(Neg 4 :% 2)
(-2) % 1
Instances
Num Q Source # | |
Read Q Source # | |
Fractional Q Source # | |
Real Q Source # | |
Defined in Data.Default.Singletons Methods toRational :: Q -> Rational # | |
Show Q Source # | |
Eq Q Source # | |
Ord Q Source # | |
SingKind Q Source # | |
(SingI num, SingI denom) => SingI (num ':% denom :: Q) Source # | |
Defined in Data.Default.Singletons | |
type Demote Q Source # | |
Defined in Data.Default.Singletons | |
type Sing Source # | |
Defined in Data.Default.Singletons |