Skip to content
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

Locally abstract types #20

Open
mimoo opened this issue Jan 25, 2023 · 2 comments
Open

Locally abstract types #20

mimoo opened this issue Jan 25, 2023 · 2 comments

Comments

@mimoo
Copy link
Contributor

mimoo commented Jan 25, 2023

(* an example with type variables that produces a bug *)
let map (x: 'a * 'a) (f:'a -> 'b) : ('b * 'b) =
	let x1, x2 = x in	
	(f x1, x2)

gives

val map : 'b * 'b -> ('b -> 'b) -> 'b * 'b = <fun>

whereas it should be (f x1, f x2)

keeping type abstracts prevents unification, which would have had the compiler yell at us:

let map (type a b) (x: a * a) (f:a -> b) : (b * b) =
	let x1, x2 = x in	
	(f x1, x2)

gives us: Error: This expression has type a but an expression was expected of type b

Also, it's useful for GADTs (see GADT section)

@mimoo
Copy link
Contributor Author

mimoo commented Jan 25, 2023

the other syntax is also useful, as noted by the manual it allows functions to be generic:

let rec f : type t1 t2. t1 * t2 list -> t1 =

or does it really make the function generic? I remember reading that you should use records to make argument of functions generic.

As in:

type ('a, 'b) generic_fn = { f : 'a -> 'b }

let fn (f : (_, _) generic_fn) = ...

but I'm not sure where this is useful, I can already write this:

utop # let fn ( f : 'a -> 'b ) ( a : 'a ) = f a;;
val fn : ('a -> 'b) -> 'a -> 'b = <fun>

@mimoo
Copy link
Contributor Author

mimoo commented Jan 25, 2023

I guess that doesn't work for functions like Fn.id or acting on containers. For example:

let concat (l1 : 'a list) (l2 : 'a list) : 'a list = ...

I wouldn't be able to apply it to something like this:

let (a : (int list * int list)) (b : (string list * string list)) ~(f : 'a list -> 'a list -> 'a list) = ...

because it would need 'a to be int at first, but then to be string later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant