Ocaml Pattern Matching Qualms - functional-programming

I'm having a bit of a problem with regards to pattern matching in Ocaml.
Basically, I need to write a function named reversed that accepts a list and checks whether or not it is in reversed order.
So far:
let rec reversed (x:int list):bool =
match x with
| [] -> true
| y::z::tl -> if y < z then false else reversed tl;
| y::[] -> true;;
It works! (to my surprise actually :P) But there is a flaw I can see, that is if there is no more tl, it would not match. Testing this returns true:
reversed [5;4;3;1;2];;
Which is perfectly understandable since there's no more tail and it simply matches to y::[]
How would I fix this?
PS: This is my first day with Ocaml. Sorry if the question is very easy :D
PPS: I am purposely only using Core. (no modules)
PPPS: I understand the case if I'm doing something fundamentally wrong, please do point it out.

The problem in your function is here :
| y::z::tl -> if y < z then false else reversed tl;
Let's look at your list : [5;4;3;1;2]
It is decomposed this way :
| 5::4::[3;1;2]
And you compare 5 and 4, and then call reverted with [3;2;1]. Wich means that the comparaison between 4 and 3 is not done ! (you can try with a list like [5;4;99;98;97], it is the unexpected result that you have).
What you should do is test on z, and then call reverted with the rest of the list. But if you try something like :
| y::z::_ -> if y < z then false else reversed z;
The compilers yells at you, because z is an int (and not an int list anymore). To solve this, you can "reconstruct" the list by adding z in front of tl :
| y::z::tl -> if y < z then false else reversed (z::tl)
Or name the list after y (which contains z) while still extracting z :
| y::(z::_ as tl) -> if y < z then false else reversed tl
As for your guess about the problem, I understand your logic but actually it does not work that way.
[] can be "named" in your decomposition, just as if it was a regular node.
Look at this example, a (bad) function who tests if the end of the list is reached :
let is_end l = match l with
| a -> false
| [] -> true;;
If you try to put that in your interpreter, you should get the following message :
Warning 11: this match case is unused.
That's because [] is already caught in the first match case. You can try with is_end [], it returns false.
The correct way to handle this is how you did it in your code :
let is_end l = match l with
| x::_ -> false
| [] -> true;;

Your program logic is wrong. You want to check if the list is reversed (decreasing?). But your program fails on input
[5;3;4;2;1]
telling you that it is reversed/decreasing. This is because you drop the 3 too early. Your middle clause should be:
| y::z::tl -> if y < z then false else reversed (z::tl);

You should use | y::z::tl -> if y < z then false else reversed (z::tl).
if y > z, you shouldn't drop z from the next round of list because z has not been compared to the next item yet.
Also you don't need ; in that line.
the correct code is
let rec reversed = function
| [] -> true
| hd::[] -> true
| hd1::hd2::tl ->
if hd1 < hd2 then false
else reversed (hd2::tl)

Here is another way to write it using some other concepts like pattern guards and wild cards:
let rec reversed = function
| [] | [_] -> true
| hd1::hd2::_ when hd1 < hd2 -> false
| _::tl -> reversed tl;;
This way there is one case for true, one for false, and one recursive.

Related

F# Strange difference in behavior of two recursive function definitions

I am trying to define a power function to compute x^y.
let rec powFunA (x,y) =
match (x,y) with
| (_,0) -> 1
| (x,y) -> x * powFunA (x,y-1);;
and
let rec powFunB x y =
match y with
| 0 -> 1
| y -> x * powFunB x y-1;;
The call powFunA (2,5) works and as expected gives me 32 as result. But somehow, I don't understand why, the second call powFunB 2 5 leads to a StackOverflowException.
I also came across a definition:
let rec power = function
| (_,0) -> 1.0 (* 1 *)
| (x,n) -> x * power(x,n-1) (* 2 *)
Can you please explain the absence of parameters and the usage of function on first line of definition.
Thanks.
This stack overflow error has to do with F#'s precedence rules. Consider this expression:
powFunB x y-1
This expression has some function application and the minus operator. In F# (as in all ML languages), function application has the highest precedence ever. Nothing can be more binding.
Therefore, the above expression is understood by the compiler as:
(powFunB x y) - 1
That is, function application powFunB x y first, minus operator second. Now, I hope, it's easy to see why this results in infinite recursion.
To fix, just apply parentheses to override precedence rules:
powFunB x (y-1)
The "parameterless" definition uses F# syntax for defining multicase functions. It's just a shortcut that allows to write = function instead of x = match x with. So, for example, the following two function are equivalent:
let f a = match a with | Some x -> [x] | None -> []
let g = function | Some x -> [x] | None -> []
Just some syntactic sugar, that's all. So the definition you found is exactly equivalent to your first snippet.

Regarding OCaml Pattern Matching Syntax

I am following this OCaml tutorial.
They provided the two functions below and said that they are equivalent.
let string_of_int x = match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
let string_of_int2 = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
My query is regarding the syntax of the above functions.
I wrote the same function but instead of | 0 -> I simply did 0 -> and the function still works in the same way. Is there any particular reason that the tutorial added the extra | in their function?
In the second function what is the use of the function keyword and why was this keyword absent in the first function?
Some people think it looks nicer and more organized, and it allows you to change the order of cases using cut & paste without having to worry about which one didn't have the |.
The function syntax is an abbreviation: function [CASES] is the same as fun x -> match x with [CASES]. There is a subtle difference, which is with function it is not possible to shadow another variable by the name of the parameter.
let string_of_int x = [EXP] is itself an abbreviation for let string_of_int = fun x -> [EXP].
So, to a close approximation, the "canonical" syntax uses fun and match, everything else is sugar. If you apply these two expansions to the two versions of the function, you will see that the same code results (modulo alpha-equivalence, of course :) ).

how to get the Column of a matrix in Ocaml

I want to print out the column of a matrix but i keep getting an error.
Error: This expression has type 'a list but an expression was expected of type int
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1);;
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list")
| []::tv -> get_column tv x
| hv::tv -> get_column2 hv x::get_column tv x;;
Matrix example [[2;5;6];[3;5;3][3;6;8]]
The first part works fine on type int list so I added the second part to go through the int list list and cut them into int list's and then tryed to get the columns of each separately.
I also tryed it this way:
let rec get_column mat x =
let rec column matr y =
if matr = [] then raise (Failure "empty list") else
if y = 1 then List.hd matr else
column (List.tl matr) y-1;
in column (List.hd mat) x :: get_column (List.tl mat) x;;
The second example translates fine but then doesn't work. I get an Exception "tl". (I'm not sure the function nesting is done right since I'm just learning Ocaml).
get_column2 - your first function, works as it should. That is it will fetch the value of each row in the matrix. It's a good helper function for you to extract the value from a list.
Your second function get_column gets all the types right, and you're accumulating everything, except that instead of stopping when you have an empty list [] you end up throwing an exception. That is your matrix example will go through just nicely, until it has no more lists to go through, then it will always throw the exception. (because the recursion keeps going till it's an empty list, and Ocaml will do as you told it too, fail when it gets an empty list.
The only thing you were missing was the exception, instead of throwing an exception, just return an empty list. That way your recursion will go all the way and accumulate till it's an empty list, and at the final step where the matrix is empty, it will append the empty list to the result, and you're golden.
So your code should be:
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1)
let rec get_column mat x= match mat with
| [] -> [] (*doesn't throw an exception here*)
| []::tv -> get_column tv x
| hv::tv -> (get_column2 hv x)::get_column tv x
Instead of throwing the exception when it's an empty list, maybe you could check if the value of x is more than the length of the inner list.
Also, here's my implementation of doing it. It's still fairly basic as it doesn't use List.iter which everyone loves, but it doesn't rely on any additional packages. It makes use of nested functions so you don't expose them everywhere and pollute the namespace.
(*mat is a list of int list*)
let get_col mat x =
let rec helper rows x = (*helper function that gets the value at x*)
match rows with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else helper t (x-1)
in
let rec wrapper mat= (*function that walks through all the rows*)
match mat with
| [] -> []
| rows::tl -> (helper rows x)::(wrapper tl) (*keep accumulating value*)
in wrapper mat
How you can visualize the [] -> [] part is that when the recursion is at it's final stage (mat is reduced to an empty list), the wrapper function returns the empty list, which will be appended to the recursion stack (since we are accumulating the values in a list as per (helper rows x)::(wrapper tl)), and the recursion will complete.
You don't hit this error with your get_column2 as you tell ocaml to stop recursing and return a value when x=1.
Edit, Additional:
As Jeffrey mentioned, a much more elegant way of handling the error is adding the case for [row], where row is the last row in the matrix. You just return (helper row x) there. And you could have the empty matrix as a failure.
Example using your code:
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list") (*fail here, as we don't want to compute a matrix with no rows.*)
| [tv] -> get_column tv x (*just return the value*)
| hv::tv -> (get_column2 hv x)::get_column tv x
When I try your first example, I don't get a type error. When I run it, I get the "empty list" failure. So your description of your problem seems wrong.
If you want to treat an empty matrix as an error, you must be very careful to handle a 1 x n matrix as your base case. I don't see that in your code.

OCaml error Failure "hd"

I try to write a simple OCaml program that returns true if the a list contains all even integers and false if it does not.
let rec allEven l =
List.hd l mod 2 = 0 && allEven (List.tl l);;
It didn't give me any error when I typed in the code. But whenever I enter a list that starts with an even number like allEven [2;3] it give me the error message "Failure "hd"". Not really sure why. Thanks!!
List.hd will raise Failure "hd" on the empty list. To correct your function, use pattern matching:
let rec allEven l =
match l with
| [] -> true
| h::t -> if h mod 2 = 1 then false else allEven t
Also, the modulo operator in OCaml is "mod" not "%"

OCaml: Pattern matching vs If/else statements

So, I'm totally new to OCaml and am moving pretty slowly in getting my first functions implemented. One thing I'm having trouble understanding is when to use pattern matching abilities like
let foo =
[] -> true
| _ -> false;;
vs using the if else structure like
let foo a =
if a = [] then true else false;;
When should I use each?
I don't think there's a clear cut answer to that question. First, the obvious case of pattern matching is when you need destructing, e.g.:
let rec sum = function
| [] -> 0
| head :: tail -> head + sum tail;;
Another obvious case is when you're defining a recursive function, pattern matching make the edge condition clearer, e.g.:
let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
instead of:
let rec factorial = function n ->
if n = 0 then
1
else
n * factorial(n-1);;
That might not be a great example, just use your imagination to figure out more complex edge conditions! ;-)
In term of regular (say C like) languages, I could say that you should use pattern matching instead of switch/case and if in place of the ternary operator. For everything else it's kind of a grey zone but pattern matching is usually preferred in the ML family of languages.
As far as I know the signifincant difference is that the expression at the guards in the match statement is a pattern which means you can do things that allow you to break apart the shape (destruct) the matched expression, as Nicolas showed in his answer. The other implication of this is that code like this:
let s = 1 in
let x = 2 in
match s with
x -> Printf.printf "x does not equal s!!\n" x
| _ -> Printf.printf "x = %d\n" x;
won't do what you expect. This is because x in the match statement does not refer to the x in the let statement above it but it's a name of the pattern. In cases like these you'd need to use if statements.
For me if..then..else is equivalent to match .. with | true -> .. | false -> .., but there's a syntax sugar if you are facing cases with nested pattern matching, using if..else in an interlace way can help you avoiding to use begin...end to separate different level of patterns
match .. with
| true ->
if .. then
match .. with
| true -> ..
| false -> ..
else
...
| false -> ...
is more compact than
match .. with
| true ->
begin
match .. with
| true ->
begin
match .. with
| true -> ..
| false -> ..
end
| false ->
...
end
| false -> ...
Pattern matching allows for deconstruction of compound data types, and in general, the ability to match pattern within a given data structure, rather than using conditionals like the if.. then structure. Pattern matching can also be used for boolean equality cases using the |x when (r == n) type construct. I should also add pattern matching is a lot more efficient than if... then.. constructs, so use it liberally!

Resources