-
Notifications
You must be signed in to change notification settings - Fork 39
Tuple projections #57
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
base: master
Are you sure you want to change the base?
Conversation
rfcs/tuple_projections.md
Outdated
let y = x.tuple_label_a in | ||
ignore (x : (tuple_label_a:int * string * bool)); | ||
(y, x.2) | ||
Error: The value `x` has type `foo` but an expression was expected of type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean discombulating_record
instead of foo
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in latest version
Unlabeled tuple projections can naturally (and efficiently) be typed using row polymorphism, in | ||
the same way object fields are typed today: | ||
```ocaml | ||
# let snd x = x.2;; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we might want to have the same semantic as with
let get_y t =
let ~y, .. = t in
y
which is rejected if I remember correctly.
We would also need to check that the back-end supports such polymorphism (I remember talking about a usefull feature similar to this one for modules with @lthls)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is rejected currently since the expected type of the pattern (i.e. the type of t
) is not known
Check to see whether the expected type is known (principally known, if in `-principal` mode). | ||
Then: | ||
* If the type is not known: raise an error stating that the projection is ambiguous. | ||
* If the type is known to be `(?l0:ty0 * ... * tyj * ... * ?ln:tyn)`: type the projection as `tyj` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in the case :
let x = ~a:1, ~b:2 in x.1
Is the example rejected because only x.a
and x.b
are accepted and not x.0
/x.1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be rejected, as you correctly surmise, the only well-typed projections for x
would be x.a
, x.b
.
This is consistent with the current pattern matching semantics i.e. the following is ill-typed:
# let x = ~a:1, ~b:2 in
let _, x1 = x in
x1;;
Error: The value x has type a:int * b:int
but an expression was expected of type 'a * 'b
The first tuple element is labeled a,
but an unlabeled element was expected
As a whole I'm strongly in favor of this feature because I consider that it would increase the quality of life when handling tuples. I also find the part about row-polymorphic tuples to be extremely interesting as it actually increases the expressiveness of OCaml's polymorphism. However I suspect this would require tweaking a few things in the back-end but hopefully not much. |
68585b9
to
0443ca7
Compare
Rendered version
TL;DR: Adds labeled and (0-indexed) unlabeled tuple projections: