suguman
suguman

Reputation: 25

Write a function with different return types in OCaml

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

Answers (2)

ivg
ivg

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

Jeffrey Scofield
Jeffrey Scofield

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

Related Questions