Reputation: 25
How can I re-write this function in OCaml so that it allows the elements of the tuple to have different types
let nth i (x,y,z) =
match i with
1->x
|2->y
|3->z
|_->raise (Invalid_argument "nth")
Upvotes: 0
Views: 644
Reputation: 35210
It can be done, but you need to fulfill the constraint that all values, returned from the function should be members of one type. The easiest solution is:
let nth i (x,y,z) =
match i with
| 1 -> `Fst x
| 2 -> `Snd y
| 3 -> `Thd z
| _ -> invalid_arg "nth tuple"
The solution demonstrates that you need to address all possible cases for the types of your tuple. Otherwise, your program will not be well-formed, and this contradicts with the static typing. The latter guarantees that your program is well-formed for any input, so that it wont fail in a runtime.
A twin solution, using ordinary ADT instead of polymorphic ones, will look something like this:
type ('a,'b,'c) t =
| Fst of 'a
| Snd of 'b
| Thd of 'c
let nth i (x,y,z) =
match i with
| 1 -> Fst x
| 2 -> Snd y
| 3 -> Thd z
| _ -> invalid_arg "nth tuple"
An exotic solution (not very practible, maybe) that uses GADT to form an existential type will look like this:
type t = Dyn : 'a -> t
let nth i (x,y,z) =
match i with
| 1 -> Dyn x
| 2 -> Dyn y
| 3 -> Dyn z
| _ -> invalid_arg "nth tuple"
Upvotes: 1
Reputation: 66808
The short answer is that it's not possible. OCaml is strongly and statically typed. A function returns a single type. Since your function returns x
, y
, and z
in different cases, then these must all be the same type.
OCaml types are not like types in the so-called dynamically typed languages. You need to think differently. The benefits are (in my opinion) tremendous.
Upvotes: 3