How do variables in pattern matching allow parameter omission? - functional-programming

I'm doing some homework but I've been stuck for hours on something.
I'm sure it's really trivial but I still can't wrap my head around it after digging through the all documentation available.
Can anybody give me a hand?
Basically, the exercise in OCaml programming asks to define the function x^n with the exponentiation by squaring algorithm.
I've looked at the solution:
let rec exp x = function
0 -> 1
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
;;
What I don't understand in particular is how the parameter n can be omitted from the fun statement and why should it be used as a variable for a match with x, which has no apparent link with the definition of exponentiation by squaring.
Here's how I would do it:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;

Your version is syntaxically correct, yields a good answer, but is long to execute.
In your code, exp is called recursively twice, thus yielding twice as much computation, each call yielding itself twice as much computation, etc. down to n=0. In the solution, exp is called only once, the result is storred in the variable y, then y is squared.
Now, about the syntax,
let f n = match n with
| 0 -> 0
| foo -> foo-1
is equivalent to:
let f = function
| 0 -> 0
| foo -> foo-1
The line let rec exp x = function is the begging of a function that takes two arguments: x, and an unnammed argument used in the pattern matching. In the pattern matching, the line
| n when n mod 2 = 0 ->
names this argument n. Not that a different name could be used in each case of the pattern matching (even if that would be less clear):
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x

The keyword "function" is not a syntaxic sugar for
match x with
but for
fun x -> match x with
thus
let rec exp x = function
could be replaced by
let rec exp x = fun y -> match y with
which is of course equivalent with your solution
let rec exp x y = match y with
Note that i wrote "y" and not "n" to avoid confusion. The n variable introduced after the match is a new variable, which is only related to the function parameter because it match it. For instance, instead of
let y = x in ...
you could write :
match x with y -> ...
In this match expression, the "y" expression is the "pattern" matched. And like any pattern, it binds its variables (here y) with the value matched. (here the value of x) And like any pattern, the variables in the pattern are new variables, which may shadow previously defined variables. In your code :
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
the variable n in the two cases shadow the parameter n. This isn't a problem, though, since the two variable with the same name have the same value.

Related

Difference between let+, let* and let()?

As the documentation on OCaml is sparse, i would appreciate if some one can explain the difference in different flavors of let usage.
I tried looking into https://dev.realworldocaml.org/toc.html, but there is no easy way to search in the website. Google search landed me to some articles, but did not get the exact explanation.
The basic form of let expressions is:
let p1 = e1
and p2 = e2
...
and pN = eN
in e
where N is at least 1. In this form, let expressions pattern matches the value that results from evaluating the RHS expressions against the LHS patterns, then evaluates the body with the new bindings defined by the LHS patterns in scope. For example,
let x, y = 1, 2 in
x + y
evaluates to 3.
When let has an operator name attached, it is the application of what is called a "let operator" or "binding operator" (to give you easier terms to search up). For example:
let+ x, y = 1, 2 in
x + y
desugars to (let+) (1, 2) (fun (x, y) -> x + y). (Similar to how one surrounds the operator + in parentheses, making it (+), to refer to its identifier, the identifier for the let operator let+, as it appears in a let expression, would be (let+).)
Finally, when a let binding has an operator name attached, all the and bindings must have operator names attached as well.
let* x = 1
and+ y = 2
and* z = 3 in
x + y + z
desugars to (let*) ((and+) 1 ((and*) 2 3)) (fun ((x, y), z) ->).
The following program is invalid and has no meaning because the let binding is being used as an operator, but the and binding is not:
let* x = 1
and y = 2 in
x + y
Binding operators are covered in the "language extensions" section of the OCaml documentation.
let () = e is merely the non-operator form of a pattern match, where () is the pattern that matches the only value of the unit type. The unit type is conventionally the type of expressions that don't evaluate to a meaningful value, but exist for side effects (e.g. print_endline "Hello world!"). Matching against () ensures that the expression has type (), catching partial application errors. The following typechecks:
let f x y =
print_endline x;
print_endline y
let () =
f "Hello" "World"
The following does not:
let f x y =
print_endline x;
print_endline y
let () =
f "Hello" (* Missing second argument, so expression has type string -> unit, not unit *)
Note that the binding operators are useful for conveniently using "monads" and "applicatives," so you may hear these words when learning about binding operators. However, binding operators are not inherently related to these concepts. All they do is desugar to the expressions that I describe above, and any other significance (such as relation to monads) results from how the operator was defined.
Consider the following code from the OCaml page on let operators.
let ( let* ) o f =
match o with
| None -> None
| Some x -> f x
let return x = Some x
If we create a very simply map:
module M = Map.Make (Int)
let m = M.(empty |> add 1 4 |> add 2 3 |> add 3 7)
If we wanted to write a function that takes a map and two keys and adds the values at those keys, returning int option, we might write:
let add_values m k1 k2 =
match M.find_opt k1 m with
| None -> None
| Some v1 ->
match M.find_opt k2 m with
| None -> None
| Some v2 ->
Some (v1 + v2)
Now, of course there are multiple ways of defining this. We could:
let add_values m k1 k2 =
match (M.find_opt k1 m, M.find_opt k2 m) with
| (None, _) | (_, None) -> None
| (Some v1, Some v2) -> Some (v1 + v2)
Or take advantage of exceptions:
let add_values m k1 k2 =
try
Some (M.find k1 m + M.find k2 m)
with
| Not_found -> None
Let operators let us write:
let add_values m k1 k2 =
let* v1 = M.find_opt k1 m in
let* v2 = M.find_opt k2 m in
return (v1 + v2)

how do I count the amount of times a (recursive) function executes itself in ocaml?

needing some help (if possible) in how to count the amount of times a recursive function executes itself.
I don't know how to make some sort of counter in OCaml.
Thanks!
Let's consider a very simple recursive function (not Schroder as I don't want to do homework for you) to calculate Fibonacci numbers.
let rec fib n =
match n with
| 0 | 1 -> 1
| _ when n > 0 -> fib (n - 2) + fib (n - 1)
| _ -> raise (Invalid_argument "Negative values not supported")
Now, if we want to know how many times it's been passed in, we can have it take a call number and return a tuple with that call number updated.
To get each updated call count and pass it along, we explicitly call fib in let bindings. Each time c shadows its previous binding, as we don't need that information.
let rec fib n c =
match n with
| 0 | 1 -> (1, c + 1)
| _ when n > 0 ->
let n', c = fib (n - 1) (c + 1) in
let n'', c = fib (n - 2) (c + 1) in
(n' + n'', c)
| _ -> raise (Invalid_argument "Negative values not supported")
And we can shadow that to not have to explicitly pass 0 on the first call.
let fib n = fib n 0
Now:
utop # fib 5;;
- : int * int = (8, 22)
The same pattern can be applied to the Schroder function you're trying to write.
You can create a reference in any higher scope like so
let counter = ref 0 in
let rec f ... =
counter := !counter + 1;
... (* Function body *)
If the higher scope happens to be the module scope (or file top-level scope) you should omit the in
You can return a tuple (x,y) where y you increment by one for each recursive call. It can be useful if your doing for example a Schroder sequence ;)

Reversing an int in OCaml

I'm teaching myself OCaml, and the main resources I'm using for practice are some problem sets Cornell has made available from their 3110 class. One of the problems is to write a function to reverse an int (i.e: 1234 -> 4321, -1234 -> -4321, 2 -> 2, -10 -> -1 etc).
I have a working solution, but I'm concerned that it isn't exactly idiomatic OCaml:
let rev_int (i : int) : int =
let rec power cnt value =
if value / 10 = 0 then cnt
else power (10 * cnt) (value/10) in
let rec aux pow temp value =
if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value / 10)
else temp in
aux (power 1 i) 0 i
It works properly in all cases as far as I can tell, but it just seems seriously "un-OCaml" to me, particularly because I'm running through the length of the int twice with two inner-functions. So I'm just wondering whether there's a more "OCaml" way to do this.
I would say, that the following is idiomatic enough.
(* [rev x] returns such value [y] that its decimal representation
is a reverse of decimal representation of [x], e.g.,
[rev 12345 = 54321] *)
let rev n =
let rec loop acc n =
if n = 0 then acc
else loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
But as Jeffrey said in a comment, your solution is quite idiomatic, although not the nicest one.
Btw, my own style, would be to write like this:
let rev n =
let rec loop acc = function
| 0 -> acc
| n -> loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
As I prefer pattern matching to if/then/else. But this is a matter of mine personal taste.
I can propose you some way of doing it:
let decompose_int i =
let r = i / 10 in
i - (r * 10) , r
This function allows me to decompose the integer as if I had a list.
For instance 1234 is decomposed into 4 and 123.
Then we reverse it.
let rec rev_int i = match decompose_int i with
| x , 0 -> 10 , x
| h , t ->
let (m,r) = rev_int t in
(10 * m, h * m + r)
The idea here is to return 10, 100, 1000... and so on to know where to place the last digit.
What I wanted to do here is to treat them as I would treat lists, decompose_int being a List.hd and List.tl equivalent.

Pattern matching functions in OCaml

Can everyone explain to me this piece of code ?
let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m
When I excute safeDiv 3 0 , what is the m and n in this case ?
In general case, when does the function match the first and second pattern ?
It is easy to see what this means once you realise that
let f x y z = e
is just a short-hand for
let f = function x -> function y -> function z -> e
That is, a function of n arguments actually is n nested functions of 1 argument. That representation is called "currying". It is what allows you to apply a function partially, e.g.
let g = f 3
returns a function of 2 arguments.
Of course, the short-hand above can be mixed freely with the explicit form on the right, and that's what your example does. You can desugar it into:
let safe_division = function n -> function
| 0 -> failwith "divide by 0"
| m -> n / m
When you execute safe_division 3 0, first, 3 is bound to the name n and the right-hand side of the declaration is then evaluated.
This is a function, so the next argument, 0, is matched against the different cases, in order. Here, it matches the first case, so the right-hand side is evaluated and an exception is thrown. In this case, the name m is never bound to anything.
If the second argument was, for example, 1, then it would have matched the second case (this case matches every possible value anyway, it's a default case), binding the name m to the value 1 and then returning the result of n / m.
let safe_division n
define a function which type is int -> ...
function
| 0 -> failwith "divide by 0"
| m -> n / m
define a function which type is int -> int
So the resulting type of the whole is int -> int -> int where n is the first argument, and m the second. The last int is the result.
let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m
is just equivalent to:
let safe_division n = fun x -> match x with
| 0 -> failwith "divide by 0"
| m -> n / m
Note fun and function are slightly different. See: Function definition.

Using Greatest Common Divisor fun

euclid :: Int -> Int
euclid n = length (filter (gcd n == 1) [1 .. n-1])
gcd :: Int -> Int -> Int
..
Your error comes from "gcd x 0 = x". The "x :: Int" is the inferred result but the type declaration of "gcd :: Int->Int->Bool" expects Bool. I expect that "gcd x 0 = (x==1)" is what you ought to have typed.
Assuming you're looking for Euler's totient function, simply call
euler_fi1 n = length $ filter ((==1).(gcd n)) [1..n-1]
The linked WP article gives a formula for calculating this directly:
euler_fi n = let
fs = Data.List.nub $ factorize n
pr = n * product [p-1 | p <- fs]
in Data.List.foldl' div pr fs
You'll need a factorize function for that:
factorize n | n > 1 = go n (2:[3,5..]) where
go n ds#(d:t)
| d*d > n = [n]
| r == 0 = d : go q ds
| otherwise = go n t
where
(q,r) = quotRem n d
Next optimization is to use primes list instead of (2:[3,5..]).

Resources