Copyright | (C) 2017 Csongor Kiss |
---|---|
License | BSD3 |
Maintainer | Csongor Kiss <kiss.csongor.kiss@gmail.com> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | Safe |
Language | Haskell2010 |
Magic product operations using Generics
These classes need not be instantiated manually, as GHC can automatically
prove valid instances via Generics. Only the Generic
class needs to
be derived (see examples).
- class HasAny sel a s | s sel k -> a where
- class HasField field a s | s field -> a where
- class HasPosition i a s | s i -> a where
- class HasType a s where
- class Subtype sup sub where
Lenses
class HasAny sel a s | s sel k -> a where Source #
Records that have generic lenses.
A lens that focuses on a part of a product as identified by some
selector. Currently supported selectors are field names, positions and
unique types. Compatible with the lens package's Lens
type.
>>>
human ^. the @Int
50>>>
human ^. the @"name"
"Tunyasz">>>
human ^. the @3
"London"
class HasField field a s | s field -> a where Source #
Records that have a field with a given name.
A lens that focuses on a field with a given name. Compatible with the
lens package's Lens
type.
>>>
human ^. field @"age"
50>>>
human & field @"name" .~ "Tamas"
Human {name = "Tamas", age = 50, address = "London"}
Get field
>>>
getField @"name" human
"Tunyasz"
setField :: a -> s -> s Source #
Set field
>>>
setField @"age" (setField @"name" "Tamas" human) 30
Human {name = "Tamas", age = 30, address = "London"}
class HasPosition i a s | s i -> a where Source #
Records that have a field at a given position.
position :: Lens' s a Source #
A lens that focuses on a field at a given position. Compatible with the
lens package's Lens
type.
>>>
human ^. position @1
"Tunyasz">>>
human & position @2 .~ "Berlin"
Human {name = "Tunyasz", age = 50, address = "Berlin"}
getPosition :: s -> a Source #
Get positional field
>>>
getPosition @1 human
"Tunyasz"
setPosition :: a -> s -> s Source #
Set positional field
>>>
setPosition @2 (setField @1 "Tamas" human) 30
Human "Tamas" 30 "London"
(Generic s, ErrorUnless i s ((&&) ((<?) 0 i) ((<=?) i (Size (Rep s)))), GHasPosition 1 i (Rep s) a) => HasPosition i a s Source # | |
Subtype relationships
class Subtype sup sub where Source #
Structural subtype relationship
sub
is a (structural) subtype
of sup
, if its fields are a subset of
those of sup
.
super :: Lens' sub sup Source #
Structural subtype lens. Given a subtype relationship sub :< sup
,
we can focus on the sub
structure of sup
.
>>>
human ^. super @Animal
Animal {name = "Tunyasz", age = 50}
>>>
set (super @Animal) (Animal "dog" 10) human
Human {name = "dog", age = 10, address = "London"}
Cast the more specific subtype to the more general supertype
>>>
upcast human :: Animal
Animal {name = "Tunyasz", age = 50}
smash :: sup -> sub -> sub Source #
Plug a smaller structure into a larger one
>>>
smash (Animal "dog" 10) human
Human {name = "dog", age = 10, address = "London"}