moduleData.Record(-- * KindsKind(typeForall,encase),Sort(specialize),-- * StylesStyle(typeK),-- * ???Value,-- * RecordsRecord(build),ExtenderPiece(ExtenderPiece),X(X),(:&)((:&)),(:::)((:=)),-- * CatenationCat,cat,-- * Mappingmap,TransformerPiece(TransformerPiece),-- * SubrecordsSubrecord(narrow))where-- PreludeimportPreludehiding(map)-- Fixitiesinfixl2:&infix3:::,:=-- * KindsclassKindkindwheredataForallkind::(*->*)->*encase::(forallsort.(Sortkindsort)=>piecesort)->ForallkindpiececlassSortkindsortwherespecialize::Forallkindpiece->piecesort-- * Stylesclass(Kind(Kstyle))=>StylestylewheretypeKstyle::*-- * ???typefamilyValuestylesort::*-- * Records{-|
The class of all record types.
A record type is a type of records without the style parameter. Therefore, it has kind @* ->
*@.
-}class(Kindkind)=>Recordkindrecordwhere{-|
A general method for building record-related &#x201C;things&#x201D;.
For each record type, this method constructs a value which is somehow related to this
record type. Such a value is called a thing. The type parameter @thing@ maps record
types to the types of their corresponding things. The first argument of @build@ gives
the thing of the empty record type while the second argument tells how to transform a
thing of an arbitrary record type into the thing of this record type extended
with an arbitrary field type.
@build@ is used, for example, to implement the function 'cat'.
-}build::thingX->(forallrecordname.(Recordkindrecord)=>Forallkind(ExtenderPiecethingrecordname))->thingrecordinstance(Kindkind)=>RecordkindXwherebuildnilThing_=nilThinginstance(Kindkind,Recordkindrecord,Sortkindsort)=>Recordkind(record:&name:::sort)wherebuildnilThingextender=letExtenderPiececonsThing=specializeextenderinconsThing(buildnilThingextender)newtypeExtenderPiecethingrecordnamesort=ExtenderPiece(thingrecord->thing(record:&name:::sort))-- |The type of empty records.dataXstyle=Xderiving(Show)-- |The type of non-empty records, consisting of an initial record and a last field.data(record:&field)style=!(recordstyle):&!(fieldstyle){-
explicit instance declaration to avoid parantheses around init records (will lead to
missing parantheses if init is constructed by an operator constructor of the same fixity as
:& which is right- or non-associative)
-}instance(Show(initstyle),Show(laststyle))=>Show((init:&last)style)whereshowsPrecenclPrec(init:&last)=showParen(enclPrec>snocPrec)$showsPrecsnocPrecinit.showString" :& ".showsPrec(succsnocPrec)lastwheresnocPrec=2{-|
The family of record fields.
Each instance of it matches arbitrary @name@ parameters and all @signalOfVal@ parameters
which are of the form @/signal/ &#x60;'Of'&#x60; /val/@. The actual choice of the instance
depends only on the @style@ parameter. The structure of fields of a specific style is
documented together with the respective style type.
-}data(name:::sort)style=!name:=Valuestylesort{-
explicit instance declaration because GHC doesn’t support deriving because of the use of the
type family Value
-}instance(Showname,Show(Valuestylesort))=>Show((name:::sort)style)whereshowsPrecenclPrec(name:=val)=showParen(enclPrec>assignPrec)$showsPrec(succassignPrec)name.showString" := ".showsPrec(succassignPrec)valwhereassignPrec=3-- * Catenation-- |The catenation of two record types.typefamilyCat(record1::*->*)(record2::*->*)::*->*typeinstanceCatrecord1X=record1typeinstanceCatrecord1(record2:&field2)=Catrecord1record2:&field2-- |The catenation of two records.cat::(Stylestyle,Record(Kstyle)record1,Record(Kstyle)record2)=>record1style->record2style->Catrecord1record2stylecatrecord1=casebuild(nilCatThingrecord1)catExtenderofCatThingattach->attachnewtypeCatThingstylerecord1record2=CatThing(record2style->Catrecord1record2style)nilCatThing::record1style->CatThingstylerecord1XnilCatThingrecord1=CatThing$\X->record1catExtender::(Stylestyle)=>Forall(Kstyle)(ExtenderPiece(CatThingstylerecord1)recordname)catExtender=encase(ExtenderPiececonsCatThing)consCatThing::CatThingstylerecord1record2->CatThingstylerecord1(record2:&name:::sort)consCatThing(CatThingattach)=CatThing$\(record2:&field2)->attachrecord2:&field2-- * Mapping-- |Application of a function to the fields of a record.map::(Stylestyle,Stylestyle',Kstyle~Kstyle',Record(Kstyle)record)=>Forall(Kstyle)(TransformerPiecestylestyle')->recordstyle->recordstyle'map=casebuildnilMapThingmapExtenderofMapThingmap->mapnewtypeTransformerPiecestylestyle'sort=TransformerPiece(Valuestylesort->Valuestyle'sort)newtypeMapThingstylestyle'record=MapThing(Forall(Kstyle)(TransformerPiecestylestyle')->recordstyle->recordstyle')nilMapThing::MapThingstylestyle'XnilMapThing=MapThing$\_X->XmapExtender::(Stylestyle)=>Forall(Kstyle)(ExtenderPiece(MapThingstylestyle')recordname)mapExtender=encase(ExtenderPiececonsMapThing)consMapThing::forallstylestyle'recordnamesort.(Sort(Kstyle)sort)=>MapThingstylestyle'record->MapThingstylestyle'(record:&name:::sort)consMapThing(MapThingmap)=MapThing$\transformer(record:&name:=val)->letTransformerPiecefun=specializetransformer::TransformerPiecestylestyle'sortinmaptransformerrecord:&name:=funval-- * Subrecords{-|
The class of all pairs of record types where the first is a subrecord of the second.
Currenty, the subrecord relation is only defined for records which do not have multiple
occurences of the same name. A records is a subrecord of another record if all field types
of the first record are also field types of the second, independently of order.
The instance declarations of @Subrecord@ use several helper classes which are hidden. One of
them is the class @Presence@. You get the error message that no instance of @Presence
/name/@ could be found if the alleged subrecord contains a name which is not present in the
alleged superrecord.
-}classSubrecordsubrecordrecordwhere-- |Converts a record into a subrecord by dropping and reordering fields appropriately.narrow::(Stylestyle)=>recordstyle->subrecordstyleinstanceSubrecordXrecordwherenarrow_=Xinstance(Dissectionrecordremaindersubnamesubsort,Subrecordsubrecordremainder)=>Subrecord(subrecord:&subname:::subsort)recordwherenarrowrecord=narrowremainder:&lookupFieldwhere(remainder,lookupField)=dissectrecordclassDissectionrecordremainderlookupNamelookupSort|recordlookupName->remainderwheredissect::recordstyle->(remainderstyle,(lookupName:::lookupSort)style)instance(PresentlookupName)=>DissectionXremainderlookupNamelookupSortwheredissect=undefinedinstance(lastSort~lookupSort)=>Dissection(init:&lookupName:::lastSort)initlookupNamelookupSortwheredissect(init:&last)=(init,last)instance(DissectioninitinitRemainderlookupNamelookupSort,(initRemainder:&lastName:::lastSort)~remainder)=>Dissection(init:&lastName:::lastSort)remainderlookupNamelookupSortwheredissect(init:&last)=(initRemainder:&last,lookupField)where(initRemainder,lookupField)=dissectinitclassPresentlookupName