| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Unison.DataDeclaration.Records
Description
This module contains various utilities related to the implementation of record types.
Synopsis
- generateRecordAccessors :: (Semigroup a, Var v) => (NonEmpty v -> v) -> (a -> a) -> [(v, a, Type v a)] -> [v] -> v -> TypeReference -> [(v, a, Term v a)]
Documentation
generateRecordAccessors Source #
Arguments
| :: (Semigroup a, Var v) | |
| => (NonEmpty v -> v) | |
| -> (a -> a) | |
| -> [(v, a, Type v a)] | Each field as |
| -> [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.