Open antalsz opened 6 years ago
What about moving the type generalization to the toplevel:
Definition sank {b} : Nat -> b -> b :=
fix sank arg_0__ arg_1__
:= match arg_0__, arg_1__ with
| Z, x => x
| S n, x => sink n x
end with sink arg_0__ arg_1__
:= match arg_0__, arg_1__ with
| Z, x => x
| S n, x => sank n x
end for sank.
@sweirich Right now, we do that when we can. The issue here is that the two function take different implicit arguments ({a}
vs. {b}
), so we can't common them up. We currently only put the longest common prefix at the top level.
Got it. deAnnotate'
in CoreSyn.hs
is an example that suffers from this limitation.
Consider the following painfully contrived Haskell code:
This is some well-founded mutual recursion (that doesn't do anything). However, thanks to
sink
taking the type parametera
andsank
taking the type parameterb
, the translated Coq code doesn't type check:In, for example
Definition sink : ... := fix sank {b} arg_0__ arg_1__ := ...
, we see thatb
is never referred to, so it is completely ambiguous!This problem also crops up when the two (or more) functions have different numbers of type arguments.
We can fix this example by simply changing
sank :: Nat -> b -> b
tosank :: Nat -> a -> a
, but it might be possible to geths-to-coq
to get this right. That would probably entail annotating the types of every function argument, something which we've avoided so far. But maybe it'd be good!