Not much better, but it should be enough to connect b
with one occurrence.
let f : 'a 'b. ([> `Foo] as 'a) -> 'b -> 'a * 'b =
fun (type b) x (y : b) -> (x,y) ;;
Not much better, but it should be enough to connect b
with one occurrence.
let f : 'a 'b. ([> `Foo] as 'a) -> 'b -> 'a * 'b =
fun (type b) x (y : b) -> (x,y) ;;
It’s a fun puzzle!
(type b)
is represented as an argument in the parse tree. So in the same way that fun x y -> r
is the same as fun x -> fun y -> r
, fun (type a) x -> r
is also the same as fun (type a) -> fun x -> r
.fun
with the return type by adding a type just before the arrow, such as fun x : string -> ""
You can combine the syntaxes: it’s possible to write the the identity function, monomorphized to ints:
fun (type a) : (int -> int) -> Fun.id
Expand the definition and you’re not far from your example:
fun (type a) : (int -> int) -> fun x -> x
Extra fun fact, you can also write:
fun (type a) -> 1
And it’s just an int.
Thanks @garrigue! That significantly reduces the duplication in my actual example.
Huh. Why? That looks dangerously easy to confuse with fun (x : string) -> ""
. Wouldn’t it make more sense for the return type to be an annotation on the return value?
I can’t comment on the “why”, but this way you can annotate both the arguments and the return value (fun (x:int) : string -> ""
). You can also annotate the return value. IIRC it parses to the same abstract syntax.