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

[WIP] migrating to GHC 8.10 and Coq 8.18. #205

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft

[WIP] migrating to GHC 8.10 and Coq 8.18. #205

wants to merge 24 commits into from

Conversation

lastland
Copy link
Collaborator

This PR is a WIP that tries to migrate hs-to-coq to GHC 8.10 and Coq 8.18.
(I have also been trying to migrate it to GHC 9, but that requires more time than I currently have, so I'm instead trying GHC 8.10 for now.)

Changes:
Since Coq 8.18, the default locality of typeclass instances has been changed to #[export], which requires a file to Require Import or Require Export a module to make these instances in scope. Unfortunately, this does not work well with our current method, as we usually only Require a module. I have changed hs-to-coq to mark all instances with an explicit #[global] locality---this might not be the best way moving forward, but it should resolve many issues for now.

Issues:
Our translation no longer produces derived instances for certain newtypes, for example: Down from Data.Ord. I suspect the reason is that the definition of these newtypes has changed from:

newtype Down a = Down a

to

newtype Down a = Down
    { getDown :: a -- ^ @since 4.14.0.0
    }

I don't know why such a change would result in hs-to-coq not producing the derived instance.

I need more time to dig into the issue. I am currently recording all these in this PR so I can remember what's going on in the future. If anyone is interested in helping us with this, please feel free to explore based on this branch---I am also happy to chat!

@lastland lastland added the help wanted Extra attention is needed label Jan 30, 2024
@lastland lastland marked this pull request as draft January 30, 2024 20:47
@motrellin
Copy link

Hi there,
first of all: I'm not an expert in this topic, just wanted to share one thought I had after I used type classes in the last weeks a lot.

This new translation

newtype Down a = Down
    { getDown :: a -- ^ @since 4.14.0.0
    }

looked to my like the :: of entrys in Coq Type Class attributes, which declares the attribute to be an Instance. Example:

Class Setoid :=
{
  carr : Type;
  ...
}

Class Group :=
{
  base_Setoid :: Setoid
  neutr : carr
  ...
}.

I noticed in my project, that problems occured, if I would have declared explicit Instances (for Example trivial_Morph made problems before I put it in the Module Framework. Concretely, it took place of some intended more generic present instances, like arguments of some function or these things like base_Setoid).

As I said, just wanted to share this as a thought, I do not have a detailed overview for this project. But I hope, that you can manage to migrate this project to a higher version.

nosewings and others added 23 commits June 25, 2024 13:43
Unclear why this is necessary. Further investigation needed.
GHC changed the way that derived instances are processed.  The new code
closely follows code from newer GHC versions, namely in the function
`tcTyClsInstDecls`.
This averts a problem caused by `GHC/Base.hs` importing `GHC/Maybe.hs`.
Add `/dev/null` to the list of files to `cat` so that `cat` doesn't try
to read from stdin, and also to ensure that the target files always get
created.
As of GHC 8.10.7, the base library has typeclass instances generated by
`GeneralizedNewtypeDeriving`.  The following definition

```haskell
class C x where
  g :: t

newtype N a = N a
  deriving (C)
```

is translated into the following instance:

```haskell
instance C a => C (N a) where
  g = GHC.Prim.coerce (g) :: t'
```

where `t'` is obtained by substituting `C a` for `x` in `t`.

This causes problems when `f` is a polymorphic function.  For example,
if `g` is `fmap`, then `t` is `forall a b. (a -> b) -> f a -> f b`.  The
resulting Gallina looks roughly like

```coq
Definition Functor__N_fmap {inst_a : Type} `{GHC.Base.Functor inst_a}
  : forall {a b, Type}, (a -> b) -> N a -> N b :=
  fun {a b : Type} => GHC.Prim.coerce (GHC.Base.fmap) : (a -> b) -> N a -> N b.
```

The problem is that `GHC.Base.fmap` has a fully-polymorphic type, but
our generated
`Functor__N_fmap` has already "eaten" the type arguments that it is
expecting.  Coq will therefore fail to find an appropriate `Coercible` instance.

The underlying problem problem is that `GeneralizedNewtypeDeriving` is
breaking our assumption that the body of a Haskell definition never
takes any additional type arguments; i.e., all type arguments should
be (implicitly) already taken before the `=`.  (Comment to that effect:
"ASSUMPTION: type variables don't show up in terms.  Broken by
ScopedTypeVariables.")

The "correct" solution probably entails
inferring the type of the method body and unifying it against the expected
method type.  But it would also require rather fishy-looking `Unpeel`
instance; something like

```coq
Instance Unpeel_forall (a : Type) (p q : a -> Type)
  (u : forall x, HsToCoq.Unpeel.Unpeel (p x) (q x)) : HsToCoq.Unpeel.Unpeel (forall x, p x) (forall x, q x).
```

which would probably have to be given explicitly.  This commit instead
takes the quick-and-dirty approach of simply detecting method bodies
that "look like" they were generated by `GeneralizedNewtypeDeriving` and
dropping their annotations.  The above Gallina code becomes instead

```coq
Definition Functor__N_fmap {inst_a : Type} `{GHC.Base.Functor inst_a}
  : forall {a b, Type}, (a -> b) -> N a -> N b :=
  fun {a b : Type} => GHC.Prim.coerce (GHC.Base.fmap).
```

This does result in local type changes relative to the original Haskell
code (e.g., the argument to `coerce` is no longer fully-quantified), but
that is probably okay.  Also, it could theoretically result in false
positives, but that is also probably okay.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants