unison-core1-0.0.0
Safe HaskellNone
LanguageHaskell2010

Unison.DataDeclaration.Records

Description

This module contains various utilities related to the implementation of record types.

Synopsis

Documentation

generateRecordAccessors Source #

Arguments

:: (Semigroup a, Var v) 
=> (NonEmpty v -> v) 
-> (a -> a) 
-> [(v, a, Type v a)]

Each field as (name, annotation, declared type). The declared type is used to build the accessor's annotation.

-> [v]

Type-level parameters of the enclosing data declaration. These become the outermost 'forall' on each accessor's annotation so the body is polymorphic in them.

-> v 
-> TypeReference 
-> [(v, a, Term v a)] 

Generate getter, setter, and modify functions for each field of a record-style data declaration.

Each accessor body is wrapped with a Ann carrying its declared type. The annotation is what lets the typechecker check (rather than infer) the accessor against fields whose declared type contains nested 'forall' quantifiers — pattern matching on such a constructor argument produces instantiated existentials that can't be re-generalized in a purely inferred result, but check-direction handling skolemizes the inner foralls and succeeds.

The setter and modifier are given their fully general types: the type variables that a field is the sole one to reference can change when that field is updated, so they are freshened in the result type. For example type These a b = { here : a, there : b } yields

These.here.set    : c -> These a b -> These c b
These.here.modify : (a -> c) -> These a b -> These c b

since here is the only field mentioning a. A variable shared by more than one field (or referenced by no field) is left fixed, so such records get the usual non-type-changing accessors.