Single record selectors as top-level functions #436
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
singletons
has traditionally singled record selectors "in-place".For example,
data T = MkT { unT :: Bool }
would be singled asdata ST :: T -> Type where SMkT :: { sUnT :: Sing b } -> ST (MkT b)
.This may seem like a sensible choice, but it has some unfortunate
consequences:
This function will not typecheck when singled:
This is because the type of
sUnT
isSing (MkT b) -> b
, whichis not general enough for the type of
sF
, which isSing (t :: T) -> Sing (F t :: Bool)
.It is impossible to single a data type with multiple constructors
that share a record name, since each occurrence of a record
selector in a data type is required to have the same type.
For these reasons and more discussed in
Note [singletons and record selectors]
inD.S.Single.Data
, wehave decided in #364 to single record selectors as simple top-level
functions. That is, we would generate the following for
sUnT
:This brings the treatment of singled record selectors in line with
promoted record selectors (note that
UnT
is also a top-level typefamily) and avoids the drawbacks mentioned above. The drawback is
that it is no longer possible to use record syntax in combination
with
SMkT
, although record selectors for singleton data constructorsare already quite buggy (see
#364 (comment)),
so this is arguably not that huge of a loss.
This change allows
D.S.Prelude.*
to single code that is much closerto the original code found in
base
. As one example, the changes inD.S.Prelude.Foldable
should give a pretty good idea of the kind ofcode that can now be singled.
Fixes #364.