-
-
Notifications
You must be signed in to change notification settings - Fork 173
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
Thoughts on introducing a minimum amount of type inference in Dhall #1370
Comments
I've thought some more on implementing some very simple and limited type inference. Here is what I believe to be the lowest-hanging-fruit case, which I call a "one-place" type inference: The change concerns only functions of the form We know the type expression If we succeed in finding This requires the following changes to the language definition:
This change affects many typing judgments because expressions may be rewritten after a typecheck. So far, rewriting affects only value expressions (but in the future we may also rewrite type expressions). This change will enable type inference in many cases where value arguments allow us to infer the preceding type arguments. An example is An example where this does not immediately work is Here is how the typing judgment needs to be modified: When type-checking a function application (
If the equivalence check
Here the judgment Maybe it will be easier if there are two kinds of typing judgments: one that has no rewriting (the current one) and another that has rewriting. I must say, this is a bit discouraging. Adding even a tiny bit of type inference (just to support the simplest use case, Is there a simpler approach to type inference? |
Not sure how easy it would be to back-port "Fall-from-Grace" type inference to Dhall. But I had this idea: We can perhaps proceed in small steps and introduce a small amount of type inference that won't break things and won't hurt either.
So far I came up with some places where type inference could be added without introducing a breaking change:
f
of type∀(A : Type) → B → C
we may applyf (A: Type) (x: B)
but we may also just writef (x: B)
, omitting the type argument. This should type-check only if knowing the type ofx
allows us to inferA
. If so, we rewritef x
tof A x
during the beta-normalization step. The normal form off x
is the beta-reduction off A x
.f : ∀(A : Type) → ∀(B : Type) → C → D
could be applied asf (x: C)
omitting the two type arguments if they can be inferred. If so, we rewritef x
tof A B x
during the beta-normalization step. The normal form off x
is the beta-reduction off A B x
.λx → b
as well as the standardλ(x : A) → b
if the type ofx
can be inferred from the type ofb
without knowing anything else (other than the current type inference context that existed when we started type-checkingλx → b
).I think about this as a "one-shot" type inference. It is unidirectional and quite limited in scope. There are no unification variables that we need to carry around. At every step, we infer one or more type parameters immediately and can rewrite our expression while preserving correctness.
Initially, this type inference may be restricted to "fully unambiguous" cases, that is, when no polymorphism is needed within the types that we infer.
So, for example,
λx → x + 1
would be allowed but notλx → λy → x y
where the inferred types ofx
andy
have to be polymorphic (x
would have the inferred type∀(A : Type) → ∀(B : Type) → A → B
).Also, a function
f x
will be rewritten tof A x
(orf A B x
, etc.) only in cases whenA
, (B
, ...) can be inferred unambiguously from knowing the type ofx
and nothing else.The result will be that type inference will work for functions where value parameters come immediately after type parameters they use. Many Dhall functions have type signatures of that form. For example:
In those cases, we would be able to apply
List/zip
simply asList/zip [1, 2, 3] ["a", "b", "c"]
without any type applications.At a later step, we might add more comprehensive type inference where a function application
f x y ... z
is rewritten tof A ... B x C ... D y E ... F z
when the type argumentsA
,B
, ...,F
inferred from knowing the combination of types ofx
,y
,z
. We might also add type inference for parameters of typeType → Type
and higher kinds. But the initial stage is just to see if it is practical to infer simple type parameters.With this proposal, there are no changes to the parser, no new syntax, no new restrictions, and no changes in existing normal forms. No existing programs become invalid, just some new programs would become valid.
The text was updated successfully, but these errors were encountered: