5
votes

In attempting to learn Ocaml and functional languages in general, I have been looking into pattern matching. I was reading this documentation, and decided to try the following exercise for myself:

Make an expression that evaluates to true when an integer 4-tuple is input such that each element in the 4-tuple is equal.

(4, 4, 4, 4) -> true

(4, 2, 4, 4) -> false

I find that doing pattern matching for the specificity of the value of the elements to not be obvious. This is the code I wrote.

let sqr x = match x with 
   (a, a, a, a) -> true 
 | (_, _, _, _) -> false ;;

Of course, this code throws the following error:

Error: Variable a is bound several times in this matching

How else can I not only enforce that x is a 4-tuple, but also of strictly integers that are equal?

(Also, of course a "square" tuple should not allow non-positive integers, but I'm more concerned with the aforementioned problem as of now). `

2
OCaml has only so-called "linear" patterns where each variable shows up once.So a pattern can't enforce equality between different parts of the mateched value.Jeffrey Scofield
Note that you can also pattern-match on functions argument as in the following : let sqr (a,b,c,d) = a=b && b=c && c==d which may seem more naturalghilesZ

2 Answers

8
votes

As you found out, unlike some other languages' pattern-matching systems, you can't do this in OCaml. What you can do is match each element of the tuple separately while using guards to only succeed if some property (like equivalence) holds across them:

let sqr x =
  match x with
  | (a, b, c, d) when a = b && b = c && c = d -> `Equal
  | (a, b, c, d) when (a < b && b < c && c < d)
                   || (a > b && b > c && c > d) -> `Ordered
  | _ -> `Boring
1
votes

You have many ways to do pattern-matching, pattern matching is not only when using the match keyword

let fourtuple_equals (a,b,c,d) = List.for_all ((=) a) [b;c;d]
val fourtuple_equals : 'a * 'a * 'a * 'a -> bool = <fun>

Here you have a pattern matching directly in the parameter in order to access your four elements tuple.

In this example I use a list to have a more concise code, but is not the more efficient.