# Attempt to code a parameterized compare

**URL:** <https://discuss.ocaml.org/t/attempt-to-code-a-parameterized-compare/4910>\
**Category:** Learning\
**Created:** [December 24, 2019, 8:21am UTC](https://discuss.ocaml.org/t/attempt-to-code-a-parameterized-compare/4910 "2019-12-24T08:21:56Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)\
**Post date:** [December 26, 2019, 2:08am UTC](https://discuss.ocaml.org/t/attempt-to-code-a-parameterized-compare/4910/3 "2019-12-26T02:08:19Z")

</div>

> [@Mohan\_Radhakrishnan](#):
>
> Moreover I couldn’t get _‘implicit’_ to compile in dune. Maybe it is not still accepted.

Modular imlicits are indeed not in the compiler trunk, tho there are these old compiler variants available from opam:

```sh
$ opam switch list-available | rg implicit
ocaml-variants 4.02.1+modular-implicits OCaml 4.02, with support for modular implicits.
ocaml-variants 4.02.1+modular-implicits-ber OCaml 4.02, with support for modular implicits and staging.

```

You may be interested in the [Modular Implicits](https://discuss.ocaml.org/t/modular-implicits/144) thread to see the state of development and read about related stuff.

> [@Mohan\_Radhakrishnan](#):
>
> ```ocaml
> let compare l r = ( List.nth l ( List.length l/ 2 )) == ( List.nth r (List.length r/2))
> 
> ```

This defines equality on two lists based on whether the elements in the middle of each list are physically equal. This is because

1. `List.nth : 'a list -> int -> 'a`, and just returns the single element located at the `nth` position in the index.
2. The `==` operator " tests the identity of its arguments, by testing the physical equality of memory representations" ([source](https://caml.inria.fr/pub/old_caml_site/FAQ/FAQ_EXPERT-eng.html#egalite))

Unless you’re after a very peculiar sort of equality, I don’t think this is what you want 🙂

Using the OCaml standard library, a minimal definition of polymorphic equality lists is just

```ocaml
let equal_lists = (=)

```

this is because the equality operator is already polymorphic. Try it in the top level!

```auto
utop # [1;2;3;4] = [1;2;3;4];;
- : bool = true
utop # ["a"; "b"; "c"] = ["x"; "y"; "z"];;
- : bool = false

```

In OCaml parlance, `compare` functions usually express inequalities rather than equality. E.g., `Int.compare : int -> int -> int` where the `Int.compare m n` is `-1` if `m < n`, `0` if `m = n`, and `1` if `m > n`. The standard OCaml library also provides a polymorphic `compare` function, and that too will work on lists out of the box.

See [the section in RWO on polymorphic compare](https://dev.realworldocaml.org/lists-and-patterns.html#terser-and-faster-patterns) for caveats and good reasons to avoid using it when performance is a concern.

If you want to define your own polymorphic comparison function, over lists is to take an argument providing a comparison of each element. Here’s one possible implementation:

```auto
utop # let rec mycompare compare xs ys = 
match xs, ys with
| [], [] -> 0 (* two empty lists are equal *)
| _, [] -> 1 (* xs is greater than ys if xs is longer *)
| [], _ -> -1 (* xs is less than ys if xs is sorter *)
| x::xs, y::ys -> 
  let c = compare x y in 
  if c <> 0 then 
    c (* The first inequality between elements is our result *)
  else 
    mycompare compare xs ys (* or keep comparing the elements *)
;;
val mycompare : ('a -> 'b -> int) -> 'a list -> 'b list -> int = <fun>

```

You use it like

```auto
utop # mycompare Int.compare [1;2;3] [9;10;11];;
- : int = -1
utop # mycompare String.compare ["foo"] ["baz"];;
- : int = 1

```

If you use a standard standard library replacment such as `base` or `containers` you’ll get the properly parameterized functions for all generally useful data structures.

---

_[View the full topic](https://discuss.ocaml.org/t/attempt-to-code-a-parameterized-compare/4910)._
