Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,252
    • Issues 5,252
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 561
    • Merge requests 561
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #16232
Closed
Open
Issue created Jan 24, 2019 by Adam Gundry@adamgundryDeveloper

Add setField to HasField

This ticket is to track the implementation of https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-record-set-field.rst

I've made a start on the implementation but have a question on which I'd appreciate some input: how should the dictionary for HasField be generated?

To recap, recall that at present, HasField x r a is coercible to r -> a so the dictionary can be constructed merely by taking the selector function for the field and wrapping it in an appropriate coercion.

With the proposal, HasField x r a will instead be represented as r -> (a -> r, a) where the first component of the tuple is an update function. The problem is how to define this update function in Core. This function should perform case analysis on the record data type, where each case replaces the value of the field being updated and preserves all the other fields. For example, given a data type data T = MkT { foo :: Int, bar :: Bool } we need to generate

\ r x -> case r of MkT {foo = _, bar = bar} -> MkT { foo = x, bar = bar }

The most obvious approach is to generate well-typed Core for the update function directly, but this seems to be rather complex, in particular because of the worker/wrapper distinction, as one ends up reconstructing much of the typechecking/desugaring for record pattern matching and construction. This also seems like a lot of work to do every time a HasField constraint is solved.

Would it be reasonable to generate update functions for fields at definition sites, as we do for selector functions? I've implemented this in the past, and it is relatively simple to generate renamed syntax to feed in to the type-checker. However, this would add some overhead for every field, even if HasField was not subsequently used, and would require some naming scheme for update functions.

Or are there other options? Is there some way to solve a HasField constraint and construct its dictionary by emitting renamed syntax for subsequent type-checking, such that subsequently solving similar constraints will use the same dictionary?

Trac metadata
Trac field Value
Version 8.7
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (Type checker)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC NeilMitchell, simonpj
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking