Declaring function using function in F# - ocaml

I'm trying to understand the following code to declare a function:
let string_of_int = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
which is the same as
let string_of_int2 x = match x with
|0 -> "zero"
|1 -> "one"
| 2-> "two"
_ -> "many
I understand The second way of declaring the function with is trying to match the input x with several possibilities that it could be. But I don't understand the first way to do it. What does function keyword do?
Also,
what does 'a'..'z' do in the following code?
let is_capital = function
| 'a'..'z' -> false
| 'A'..'Z' -> true
|_ -> failwith "Not a valid letter"
Why can't I have a function like this:
let examplefunc = function
|"string"-> Printf.printf "a string"
|3 -> Printf.print "an integer"
|true-> Printf.printf "a boolean"
|- -> Printf.printf "whatever"

The function keyword is a variant of fun that takes in account that the behavior of the function often directly depends on the value of the argument. For instance, if we start with the following definition of the factorial function:
For a positive integer n, n! is 1 if n = 0, and n * (n-1)! otherwise
then the natural translation to OCaml is
let factorial = function
| 0 (* if n = 0 *) -> 1
| n (* otherwise *) -> n * factorial (n-1)
like you said this strictly equivalent to
let factorial = fun n -> match n with
| 0 (* if n = 0 *) -> 1
| n (* otherwise *) -> n * factorial (n-1)
but when the argument of the function is immediately deconstructed in a pattern matching, it may be more readable to use function directly.
Concerning '0'..'9', those are range pattern that matches all characters (i.e '0'|'1'|'2'|'3'|'4'|..| '9' between the lower and upper bounds (included) of the range (following the ascii ordering of characters)
let is_digit = function '0'..'9' -> true | _ -> false
is_digit '0' (* returns true *);;
is_digit 'a' (* returns false *);;

Related

Why does this function accept the 2nd param

The function aux only has one param n. Why can it accept list at the bottom?
# let length list =
let rec aux n = function
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 list;;
val length : 'a list -> int = <fun>
The function expression produces a function of one argument.
# function [] -> 0 | _ -> 1;;
- : 'a list -> int = <fun>
Now, if you write a function f that takes a parameter n, and whose body contains function, as follows:
# let f n = function [] -> 0 | _ -> n;;
val f : int -> 'a list -> int = <fun>
Then f is a function that takes n and returns a function of a single argument.
# f 3;;
- : '_weak1 list -> int = <fun>
The returned value is a function that takes a list of some unknown type of values, and returns an integer (the _weak prefix is related to Weak Type Variables, this is not important here).
Since the returned value is a function, you can apply it:
# (f 3) ["test"];;
- : int = 3
You can drop the parentheses around f 3 because that's how function application is grouped by default:
# f 3 ["test"];;
- : int = 3
So what looks like a function taking two arguments is in fact a function taking one argument, evaluating to a function to which we apply the second argument.
(See also Currying)
The function keyword introduces a function which takes a single argument, which it pattern matches.
This is equivalent to:
let length lst =
let rec aux n lst =
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
Or...
let length lst =
let rec aux n =
fun lst ->
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
function keyword will match the last argument, even it’s not declared in the left side of =.
Compare with match .. with, the match needs the argument name show up.

unable to understand why im not getting the proper output

I've written a code for streams of factorial.
type 'a lazee = 'a hidden ref
and 'a hidden = Value of 'a
| Thunk of (unit -> 'a)
let demand (l: 'a lazee) : 'a =
force l;
match !l with
| Value v -> v
| Thunk f -> raise (Failure "shouldn't happen like this")
let force (l: 'a lazee) : unit = match !l with
| Value _ -> ()
| Thunk f -> l := Value (f ())
let rec zip (f: 'a -> 'b -> 'c) (s1: 'a stream) (s2: 'b stream) : 'c stream =
match s1, s2 with
| Cons (h1, t1), Cons (h2, t2) ->
Cons (f h1 h2, delay (fun () -> zip f (demand t1) (demand t2)))
let delay (unit_to_x: unit -> 'a) : 'a lazee =
ref (Thunk unit_to_x)
let nats = from 1
let mul_p x y =
let () = print_endline ("multiplying " ^ string_of_int x ^ " and " ^
string_of_int y ^ ".")
in x * y
let rec factorials () =
Cons (1, delay (fun () -> zip mul_p nats (factorials ())))
let facts = factorials ()
I want to get the output like this,
multiplying 1 and 1.
multiplying 2 and 1.
multiplying 3 and 2.
multiplying 4 and 6.
multiplying 5 and 24.
the above output generates when I execute the following command in file itself: let () =
assert (take 5 facts = [1; 1; 2; 6; 24])
but when I execute the file in OCaml, I get multiple multiplications like this,
multiplying 1 and 1.
multiplying 1 and 1.
multiplying 2 and 1.
multiplying 2 and 1.
multiplying 3 and 2.
multiplying 1 and 1.
multiplying 2 and 1.
multiplying 3 and 2.
multiplying 4 and 6.
multiplying 1 and 1.
multiplying 2 and 1.
multiplying 3 and 2.
multiplying 4 and 6.
multiplying 5 and 24.
can someone fix this for me, I've tried several trial and errors but couldn't figure it out. thanks!
Assuming your implementation of demand is correct, your problem is indeed your definition of factorials:
let rec factorials () =
Cons (1, delay (fun () -> zip mul_p nats (factorials ())))
Here, the inner call to factorials () recreate a new stream value with a fresh inner reference and thus lose all sharing with the external call. Consequently, it needs to recompute all previously computed value of factorials without any memoization.
Thus, we need to define factorials as a single recursive value
let rec factorials =
Cons(1, ref (Thunk (fun () -> zip mul_p nats factorials)))
Note that the function delay cannot used directly because the recursive value analyzer needs to be convinced that the recursive value, factorial, is correctly used in its own body.

getting error when trying to parse integer

Im trying to run an interpreter I made in ocaml and when i to push in a negative value i.e. let e1 = run [PushI -2; PushI 2; LessThan] []. I am getting a syntax error for my parse_int function. I'm trying to write the part of the function that allows for the input of a negative number
type stackVal =
I of int
type command = PushI of int
let rec run (commands : command list) (stack: stackVal list) : stackVal list =
match (commands , stack) with
| (PushI i :: rest, _ ) -> run rest (I i :: stack)
let to_string (s : stackVal) : string =
match s with
| I i -> string_of_int i
let parse_command (s:string) : command =
match take_while is_alpha (String.trim s) with
| ("PushI" , p) -> let Some i = parse_int (String.trim p) in PushI i
let parse_int (s : string) : int option =
match int_of_string s with
| String.get n 0 = '-' -> Some -String.sub n 1 len
| n -> Some n
| exception _ -> None
There is a problem with the pattern-matching of your parse_int function.
match int_of_string s with
| String.get n 0 = '-' -> Some -String.sub n 1 len
| n -> Some n
| exception _ -> None
The first clause here is invalid as "String.get n 0 = '-'" is not an integer constructor. You could write 1 which matches only the integer 1 or _ whitch matches any integer or n which matches any integer and binds it to the name n for the rest of the clause. You can have a look at the manual for more informations.
If you wanted to check if the first char of the string is - pattern matching is not the right tool to do it, simply use an if then else.
However, note that int_of_string works just fine on negative integers, so there is no need to do that part by yourself.
Unrelated, but i noticed that you call the parse_int in the parse_command function. In that case you should define parse_int before parse_command.

Pattern Matching with Varying types of Tuples

I'm trying to figure out how to pattern match with user defined types. For example I have this type.
Type custom_type = B of bool | I of int | S of string | C of custom_type * custom_type
I want to pattern match these types, and say for example count the number of ints in a value. Example value:
C(C(B true, I 5), C(S "example", B false))
I think I'm very close to figuring it out, I know I need to use wildcards but I can't write out every instance there could be, because there are numerous varying values I need to check.
Thanks!
Edit: Code that isn't working:
let num = 0
let rec count_ints (c: custom_type):int =
match c with
| C (I(_), _) -> num + 1
| C (_, I(_)) -> num + 1
| C (C(_), _) -> count_ints c
| C (_, C(_)) -> count_ints c
You should be thinking of having 4 cases in your function, one for each constructor. You don't need to match what's inside these constructors because you can call yourself recursively to handle that.
Your code calls count_chars, but there's no function of that name. If it's supposed to be count_ints, then this is not a good recursive call. You must call recursively on a smaller problem. If you just pass c along to yourself recursively you'll get infinite recursion.
let rec count_ints (c: custom_type):int =
match c with
| I _ -> 1
| C (c1,c2) -> count_ints c1 + count_ints c2
| _ -> 0

match case unused in OCaml

I want to build a list of type (char, 'a list) list where each char is an upper case letter of the alphabet. I'am getting a warning Warning 11: this match case is unused. for the second match case on get_list. I did some prints on the first case and found out len get's there with value 0, so it never uses the second case. What's happening?
let rec get_list abc i len =
match i with
| len -> []
| _ -> ((String.get abc i), [])::get_list abc (i + 1) len
in
let rec print_list l =
match l with
| [] -> ()
| h::t -> print_char(fst h);print_list t
in
let abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in
let abc_l = get_list abc 0 (String.length abc) in
print_list abc_l;;
The reason it doesn't work
When you write
match i with
| len -> []
| _ -> ["..."]
len is a generic pattern, which hasn't anything to do with the len define above. In a pattern matching you define only how the variable should look like, you describe it's general "structure", the variable names are used to name the differents parts of the pattern matching, and are new variables. For example with lists you can do:
match my_list with
| [x,y,z] -> x+y+z
| x :: r -> x + (List.length r)
| anything_else -> List.length anything_else
When you put '_' it's only a convention to say "I don't mind which value it is, I don't need it". Here is another example with tuples:
match my_tuple with
| (a,b) -> a+b
A solution : conditionnal pattern matching
If you want to put condition in a pattern matching you can use the when keyword :
match i with
| n when n = len -> []
| _ -> ["..."]
Another example that "sort" a tuple:
match my_tuple with
| (a,b) when a>b -> (a,b)
| (a,b) -> (b,a)
Or just use conditions with integers :
if i = len then []
else ["..."]
You can also note that you can do pattern matching within functions :
let f (a,b) = a+b
The len in your pattern is a new variable introduced by the pattern. As a pattern, its meaning is that it will match anything at all. Thus, the next pattern _ will never match.
As #AlexanderRevyakin says, this new variable len is hiding the parameter that's also named len.
It is not the case that the len in your pattern represents the value of the parameter len. OCaml patterns contain only new variables (to which pieces of the matched value are bound) and constants. They don't contain expressions that are evaluated at run time. For that you want to use if/then/else (as #AntonTrunov points out).