generic-lens- Generic data-structure operations exposed as lenses.

Copyright(C) 2017 Csongor Kiss
MaintainerCsongor Kiss <>
Safe HaskellSafe




Magic record 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).


Subtype relationship

class Subtype sub sup where Source #

Structural subtype relationship

sub is a (structural) subtype of sup, if its fields are a subset of those of sup.

Minimal complete definition

upcast, smash


upcast :: sub -> sup Source #

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"}


(GSmash * (Rep a) (Rep b), GUpcast (Rep a) (Rep b), Generic a, Generic b) => Subtype a b Source #

Instances are created by the compiler


upcast :: a -> b Source #

smash :: b -> a -> a Source #

super :: forall sup sub. Subtype sub sup => 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"}

Magic lens

class HasField field a s | s field -> a where Source #

Records that have a field with a given name.

Minimal complete definition



label :: Lens' s a Source #

Lens focusing on a field with a given name. Compatible with the lens package.

 type Lens' s a
   = forall f. Functor f => (a -> f a) -> s -> f s
>>> human & label @"name" .~ "Tamas"
Human {name = "Tamas", age = 50, address = "London"}


(Generic s, (~) (Maybe Type) (Contains field (Rep s)) (Just Type a), GHasField field (Rep s) a) => HasField field a s Source #

Instances are generated on the fly for all records that have the required field.


label :: Lens' s a Source #

Getter and setter

getField :: forall field a s. HasField field a s => s -> a Source #

Get field

>>> getField @"name" human

setField :: forall field a s. HasField field a s => a -> s -> s Source #

Set field

>>> setField @"age" (setField @"name" "Tamas" human) 30
Human {name = "Tamas", age = 30, address = "London"}