Copyright | (C) 2020 Csongor Kiss |
---|---|
License | BSD3 |
Maintainer | Csongor Kiss <kiss.csongor.kiss@gmail.com> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Structural subtype relationships between sum types.
Prisms
Running example:
>>>
:set -XTypeApplications
>>>
:set -XDataKinds
>>>
:set -XDeriveGeneric
>>>
import GHC.Generics
>>>
import Control.Lens
>>>
:{
data Animal = Dog Dog | Cat Name Age | Duck Age deriving (Generic, Show) data FourLeggedAnimal = Dog4 Dog | Cat4 Name Age deriving (Generic, Show) data Dog = MkDog { name :: Name , age :: Age } deriving (Generic, Show) type Name = String type Age = Int dog, cat, duck :: Animal dog = Dog (MkDog "Shep" 3) cat = Cat "Mog" 5 duck = Duck 2 dog4, cat4 :: FourLeggedAnimal dog4 = Dog4 (MkDog "Snowy" 4) cat4 = Cat4 "Garfield" 6 :}
class AsSubtype sub sup where Source #
Structural subtyping between sums. A sum
Sub
is a subtype of another sum
Sup
if a value of
Sub
can be given (modulo naming of constructors)
whenever a value of
Sup
is expected. In the running example for instance,
FourLeggedAnimal
is a subtype of
Animal
since a value of the former can
be given as a value of the latter (renaming
Dog4
to
Dog
and
Cat4
to
Cat
).
injectSub , projectSub | _Sub
_Sub :: Prism' sup sub Source #
A prism that captures structural subtyping. Allows a substructure to be injected (upcast) into a superstructure or a superstructure to be downcast into a substructure (which may fail).
>>>
_Sub # dog4 :: Animal
Dog (MkDog {name = "Snowy", age = 4})
>>>
cat ^? _Sub :: Maybe FourLeggedAnimal
Just (Cat4 "Mog" 5)
>>>
duck ^? _Sub :: Maybe FourLeggedAnimal
Nothing
injectSub :: sub -> sup Source #
Injects a subtype into a supertype (upcast).
projectSub :: sup -> Maybe sub Source #
Projects a subtype from a supertype (downcast).
Instances
AsSubtype a Void Source # |
See Note [Uncluttering type signatures] _Sub :: (AsSubtype sub sup, Data.Profunctor.Choice.Choice p, Applicative f) => p sub (f sub) -> p sup (f sup) |
AsSubtype a a Source # |
Reflexive case >>> _Sub # dog :: Animal Dog (MkDog {name = Shep , age = 3}) |
Context sub sup => AsSubtype sub sup Source # | |
AsSubtype Void a Source # |
See Note [Uncluttering type signatures]
>>> :t +d _Sub
|