Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"as" keyword in OCaml

In the answers for the tutorials for OCaml available at this site, some of the solutions, including the one for eliminating consecutive duplicates of list elements, is written as such:

let rec compress = function
    | a :: (b :: _ as t) -> if a = b then compress t else a :: compress t
    | smaller -> smaller;;

What is the relevance of the line a :: (b:: _ as t)? Why can't I write it as a :: b :: t instead?

like image 778
Vincent Tjeng Avatar asked Nov 05 '14 23:11

Vincent Tjeng


People also ask

What does -> mean in OCaml?

The way -> is defined, a function always takes one argument and returns only one element. A function with multiple parameters can be translated into a sequence of unary functions.

What does type A mean in OCaml?

The type 'a is a type variable, and stands for any given type. The reason why sort can apply to lists of any type is that the comparisons (=, <=, etc.) are polymorphic in OCaml: they operate between any two values of the same type. This makes sort itself polymorphic over all list types.

What does H :: t mean in OCaml?

The pattern h :: t matches any non-empty list, calls the head of the list h (one element, the first one), and the tail of the list t (zero or more elements after the first one). The operator :: is the list constructor (often called "cons"), which is why these patterns match lists.

What is pattern matching OCaml?

Pattern matching comes up in several places in OCaml: as a powerful control structure combining a multi-armed conditional, unification, data destructuring and variable binding; as a shortcut way of defining functions by case analysis; and as a way of handling exceptions.


2 Answers

The t in b :: _ as t is bound to b :: _. So the meaning is different. If you use the pattern a :: b :: t you would need to say compress (b :: t), which is a little less elegant and a tiny bit less efficient.

like image 111
Jeffrey Scofield Avatar answered Oct 18 '22 16:10

Jeffrey Scofield


The keyword as binds a name to all or part of a pattern. Once bound, the name can be used instead of the pattern it represents. In your "compress" function, t is bound to the pattern b :: _. Once t is bound, it can be used in subsequent expressions, as in the rest of the "compress" function.

as name binding occurs left-to-right, unlike most languages (excepting C's typedef). Also, :: appears to have higher precedence than as.

Therefore, (b :: _ as t) is equivalent to ((b :: _) as t). This can be confusing for those used to right-to-left bindings. Note that a :: (b :: _) as t will bind the whole pattern a :: b :: _ to t, due to the precedence mentioned above.

Reference:

  • http://caml.inria.fr/pub/docs/manual-ocaml/patterns.html#hevea_manual.kwd7
  • http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora016.html.
like image 37
earthfront Avatar answered Oct 18 '22 16:10

earthfront