What does the name binding with the as- keyword do in this exercise: https://ocaml.org/problems#17
# let split list n =
let rec aux i acc = function
| [] -> List.rev acc, []
| h :: t as l -> if i = 0 then List.rev acc, l
else aux (i - 1) (h :: acc) t
in
aux n [] list;;
Does it allow us to choose in the if / else clause whether the tail t
or the list l
is used in the function pattern matching?
What is the common use of name binding in functional Programming?
Thank you very much.
CodePudding user response:
The as
keyword allows you to bind a name to larger and smaller parts of a pattern. In the example you provided:
let split list n = let rec aux i acc = function | [] -> List.rev acc, [] | h::t as l -> if i = 0 then List.rev acc, l else aux (i - 1) (h :: acc) t in aux n [] list
l
is bound to the entire list, and h
is bound to the head of the list and t
to the tail.
Without as
you might write:
let split list n =
let rec aux i acc = function
| [] -> List.rev acc, []
| h::t -> if i = 0 then List.rev acc, (h::t)
else aux (i - 1) (h :: acc) t
in
aux n [] list
Keep in mind that as
is "greedy" to its left, and parentheses may be needed to disambiguate precedence.
E.g.
h::h'::t as lst
The entire list is bound to lst
.
If you want to to bind the tail, but also the second element in a list:
h::(h'::_ as tl)