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. )
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 *)