Question

I have the following bit of code, which I'd like to return either a boolean or a tuple. (The functions isvariable and dont_care both return booleans, fyi)

let match_element (a, b) =
if a = b then true
else if (dont_care a) || (dont_care b) then true
else if (isvariable a) then (a, b)
else if (isvariable b) then (b, a)
else false;;

Currently, it raises the following error:

Is there any way of resolving this?

This expression has type 'a * 'b
but an expression was expected of type bool

(This function is based on instructions for a Python program, and I'm not sure if it's possible in OCaml. )

Was it helpful?

Solution

What you want is, very roughly speaking, ad-hoc polymorphism or overloading. It is impossible in OCaml, and more importantly, we do not want to have it in OCaml.

If you want to have a function which returns multiple types, then you have to define a new "sum" type which can express these types: here, you want to return a boolean or a tuple, so a new type which means "a boolean or a tuple". In OCaml we define such a type like:

type ('a, 'b) t = Bool of bool
                | Tuple of 'a * 'b

Using this new sum type your code should look like:

type ('a, 'b) t = 
  | Bool of bool
  | Tuple of 'a * 'b

let match_element (a, b) =
  if a = b then Bool true
  else if dont_care a || dont_care b then Bool true
  else if is_variable a then Tuple (a, b)
  else if is_variable b then Tuple (b, a)
  else Bool false;;

The type t here with two parameters ('a and 'b) can be too general for your purpose, but I cannot guess what you want to do from the context. There may be nicer type definition which suits with your intention, like:

type element = ... (* Not clear what it is from the context *)

type t =
  | I_do_not_care        (* Bool true in the above definition *)
  | I_do_care_something  (* Bool false in the above definition *)
  | Variable_and_something of element * element  (* was Tuple *)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top