Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic derivation of instances #1293

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

normanrink
Copy link
Contributor

For types of the form

data NewTy(<params>) = NewCon(WrappedTy(<params>))

if there is an instance Class(WrappedTy(<params>)), a Class instance for NewTy(<params>) can be automatically derived. This PR implements automatic instance derivation with the syntax

deriving instance Class(NewTy(<params>)) <givens>

Note that automatic instance derivation is asked for in issue #945, but the approach taken in this PR differs from extending DictExpr n with a new contructor NewtypeDict (DictType n) (DictExpr n), as suggested in issue #945. Instead, this PR synthesises an InstanceDef for Class(NewTy(<params>)) from the definition of instance Class(WrappedTy(<params>)).

The main difficulty in synthesising the InstanceDef for Class(NewTy(<params>)) is converting the methods of instance Class(WrappedTy(<params>)), which operate on WrappedTy(<params>), to methods that work with NewTy(<params>). Since the types WrappedTy(<params>) and NewTy(<params>) are isomorphic, this conversion is generally possible. Note that in order to facilitate this conversion, an isomorphism between WrappedTy(<params>) and NewTy(<params>) must be exhibited, consisting of a pair of maps, namely of a (forward-directed) isomorphism and its (backward-directed) inverse.

This change adds the following:
- syntax `deriving instance ...` for automatic derivation of
  instances/dictionaries
- constructor `NewtypeDict` for dictionary expressions
- synthesis of `NewtypeDict` dictionaries
- (currently incorrect) simplification of method applications on
  `NewtypeDict dictionaries
Methods are constructed by first synthesizing a dictionary for
the instance that is derived from. Those methods are then converted
to methods suitable for the derived instance by using an isomorphism
between types.
This constructor was introduced for automatic derivation of
instances. This constructor is no longer needed.
This constructor was introduced for automatic derivation of
instances. This constructor is no longer needed.
Specifically, by representing isomorphisms as abstractions (`Abs`) we
avoid the need for evidence of `Emits`.
Also fix the type of an `App` expression that is constructed
during method conversion.
This simplification has led to the removal of an unsafe coercion.
…tion.

The current implementation of automatic instance derivation synthesizes
methods (for the derived instance) in a way that is guided by the method
types in the instance that we are deriving _from_. For the method synthesis
to work correctly certain types (i.e. the type we are deriving _from_ and
the type we are deriving an instance _for_) must not be mentioned in the
type of the class method that corresponds to the instance method that is
being synthesized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant