-
Notifications
You must be signed in to change notification settings - Fork 72
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
Bounded quantification (or, typeclasses) #5
Comments
it's simple. Add a type ty =
| ...
| Implicit of ty * ty (* the first element is the instance *) Further, you should maintain a scope from symbols(unique) to types, remember the current scope when instantiating. Finally(after type inference), access the remembered scope(symbols to types) and the implicit type, search the symbol available in scope, select the one whose type is the most specific, take this symbol as the argument of the bounded function. type 'a eq = { (==) : 'a -> 'a -> bool }
let int_eq = {(==) = compare}
let (==) : {'a eq} => 'a -> 'a -> bool = fun inst ->
fun lhs rhs -> inst.(==) lhs rhs
(* during type inference and compilation, we resolved {'a eq} to be {int eq}, and *)
(* remember the available symbols*)
1 == 2
(* after type infer, we know int_eq is the available symbol whose type is the most specific *) |
It's been a while since I've looked into implicits, but IIRC the difficult parts are:
Haskell and Scala have different solutions to these problems, neither of which I particularly like... I have some ideas how to solve them, but they're very complex and not very well developed :) |
the higher order caseslet list_eq : forall a. eq a => eq (list a) = fun inst -> {
(==) = List.forall inst.eq
} The instantiations cause passing into implicit arguments, let's see an example: [1] == [2] After type inference, for Call(
Instance(
type = forall a. eq (list a),
scope = (* available symbols of this site *),
expr= (*unique symbol of == *)
),
(*ir of [1] *),
(*ir of [2] *)
) We can perform instance resolution, and find out I personally prefer not to support polymorphic recursions without explicit annotations. the uniqueness checkingI think most specific instance just answers your questions.. instance coherence problemAs for instance coherence problem, this is quite a big topic, and thank you very much to bring this here. There're so many solutions to this, orphan instances and contextual dispatching(in Haskell, you can also write the Labelled classes, though a bit verbose than compiler builtin support), IIRC are the most popular 2 ways. However, there is a commonly adapted design for the overlaps or duplications of instance resolution, Not every user of a programming language is clever(enough), they might not know what they're doing, so use a conservative approach by default, and tell them other solutions are available then, I cannot criticize the designers if they do this. |
No description provided.
The text was updated successfully, but these errors were encountered: