I cant understand some things in my code. It is program in OCaml which generates all distinct pairs from elements in list. Here's my code:
let rec tmp f list x =
match list with
| [] -> x
| h :: t -> f h (tmp f t x);;
(* ^ ^ (^ ) (1) *)
let rec distinctpairs lst =
match lst with
| [] -> []
| h :: t -> tmp ( fun x lt -> (h,x)::lt) t (distinctpairs t);;
(* ^ ^ (2) *)
Do function tmp returns three values ?
How i can give an argument to func, when i dont know what is x?
When i assume that tmp return three values, that why when I giving as arg to tmp the ( fun x lt -> (h,x)::lt) argument, and it works?
1. Do function tmp returns three values ?
let rec tmp f list x =
match list with
| [] -> x
| h :: t -> f h (tmp f t x);;
The simple answer to this question is no.
f h (tmp f t x) is not three value, instead, it is a function execution/application on f.
2. How i can give an argument to func, when i dont know what is x?
let rec distinctpairs lst =
match lst with
| [] -> []
| h :: t -> tmp ( fun x lt -> (h,x)::lt) t (distinctpairs t);;
The truth here is you know x. x is defined as a parameter of the anonymous function fun x lt -> (h, x)::lt.
When i assume that tmp return three values, that why when I giving as arg to tmp the ( fun x lt -> (h,x)::lt) argument, and it works?
First of all, when ocaml sees tmp f list x, ocaml does not know anything but tmp accepts 3 parameters.
When ocaml reaches | [] -> x, it knows whatever type x is, the tmp will return the same type as x.
When ocaml reaches | h::t -> f h (tmp f t x), it knows f must be a function and f will have 2 parameters: one with type of h and one with type of x
Then in your distinctpairs function, ( fun x lt -> (h,x)::lt) is an anonymous function which really matches the prediction above.
A better way to write the two functions:
let rec tmp f x = function
| [] -> []
| h :: t -> f h (tmp f x t)
let rec distinctpairs = function
| [] -> []
| h :: t -> tmp (fun x lt -> (h,x)::lt) (distinctpairs t) t
I also suggest you to read Real World Ocaml book. It is the newest and most comprehensive book on OCaml and it is good.
When you try to enter functional programming world, there is no shortcut. It is not like you learn Spanish as an English speaker. It is more like learning Chinese/Japanese as an English speaker.
The whole idea is quite different from Java or C# or C, and of course, much better than Java (my personal feeling). So I suggest you to learn from ground.
Related
When declaring a function, I've 3 different ways:
let f x = ...
let f = (fun x -> ...)
let f = function
| ... -> (pattern matching)
It's this last one that I don't fully understand how it works.
I was doing a function that, considering a list (we'll assume it has integers in it but could be anything), reverses it, pretty basic, but with a complexity of O(n). After struggling for an hour at least I check the answer, and it is written like this:
let reverse lst =
let rec aux acc = function
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
I thought that using the key word function was just another way of doing patter matching, but when I do this:
let reverse lst =
let rec aux acc =
match aux with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
It doesn't work, and idk why. On top of that, why can we add tl at the end of the first function? Isn't aux a single argument function?
There are a few problems with this question. First, the code you give as the solution for reverse is not valid OCaml. It matches aux (which is a function) against list patterns. Most likely aux was supposed to be acc. But even so it doesn't seem right because it should have two arguments (the accumulated result and the input that still needs to be processed).
Second, your two code examples are the same. You seem to be saying that one works and one doesn't work. That doesn't make sense since they're the same.
IMHO you need to rewrite the question if you want to get a helpful answer.
Ocaml uses currying, which means that a two-argument function is the same thing that a function whose return value is a function.
To define a two-argument function, you can combine all the ways you know of creating one-argument functions:
let f x y = x + y
let f x = (fun y -> x + y)
let f x = function
| y -> x + y
let f = (fun x -> (fun y -> x + y))
let f = function
| x -> function
| y -> x + y
let f x = (let g y = x + y in g)
etc, etc.
All these definitions for f lead to the same result:
val f : int -> int -> int = <fun>
# f 3 4;;
- : int = 7
Note that the signature of f is:
val f : int -> int -> int = <fun>
If we added parentheses to better understand this signature, it would be this:
val f : int -> (int -> int) = <fun>
Meaning that f is a one-argument function whose return value is a one-argument function whose return value is an int.
Indeed, if we partially apply f:
# f 3;;
- : int -> int = <fun>
# let add_three = f 3;;
val add_three : int -> int = <fun>
# add_three 4;;
- : int = 7
The code you give at the end of your question is wrong. It's most likely intended to be this:
let reverse lst =
let rec aux acc l =
match l with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst;;
val reverse : 'a list -> 'a list = <fun>
# reverse [1;2;3;4;5];;
- : int list = [5; 4; 3; 2; 1]
In OCaml, it seems that "fun" is the binding operator to me. Does OCaml have built-in substitution? If does, how it is implemented? is it implemented using de Bruijn index?
Just want to know how the untyped lambda-calculus can be implemented in OCaml but did not find such implementation.
As Bromind, I also don't exactly understand what you mean by saying "Does OCaml have built-in substitution?"
About lambda-calculus once again I'm not really understand but, if you talking about writing some sort of lambda-calculus interpreter then you need first define your "syntax":
(* Bruijn index *)
type index = int
type term =
| Var of index
| Lam of term
| App of term * term
So (λx.x) y will be (λ 0) 1 and in our syntax App(Lam (Var 0), Var 1).
And now you need to implement your reduction, substitution and so on. For example you may have something like this:
(* identity substitution: 0 1 2 3 ... *)
let id i = Var i
(* particular case of lift substitution: 1 2 3 4 ... *)
let lift_one i = Var (i + 1)
(* cons substitution: t σ(0) σ(1) σ(2) ... *)
let cons (sigma: index -> term) t = function
| 0 -> t
| x -> sigma (x - 1)
(* by definition of substitution:
1) x[σ] = σ(x)
2) (λ t)[σ] = λ(t[cons(0, (σ; lift_one))])
where (σ1; σ2)(x) = (σ1(x))[σ2]
3) (t1 t2)[σ] = t1[σ] t2[σ]
*)
let rec apply_subs (sigma: index -> term) = function
| Var i -> sigma i
| Lam t -> Lam (apply_subs (function
| 0 -> Var 0
| i -> apply_subs lift_one (sigma (i - 1))
) t)
| App (t1, t2) -> App (apply_subs sigma t1, apply_subs sigma t2)
As you can see OCaml code is just direct rewriting of definition.
And now small-step reduction:
let is_value = function
| Lam _ | Var _ -> true
| _ -> false
let rec small_step = function
| App (Lam t, v) when is_value v ->
apply_subs (cons id v) t
| App (t, u) when is_value t ->
App (t, small_step u)
| App (t, u) ->
App (small_step t, u)
| t when is_value t ->
t
| _ -> failwith "You will never see me"
let rec eval = function
| t when is_value t -> t
| t -> let t' = small_step t in
if t' = t then t
else eval t'
For example you can evaluate (λx.x) y:
eval (App(Lam (Var 0), Var 1))
- : term = Var 1
OCaml does not perform normal-order reduction and uses call-by-value semantics. Some terms of lambda calculus have a normal form than cannot be reached with this evaluation strategy.
See The Substitution Model of Evaluation, as well as How would you implement a beta-reduction function in F#?.
I don't exactly understand what you mean by saying "Does OCaml have built-in substitution? ...", but concerning how the lambda-calculus can be implemented in OCaml, you can indeed use fun : just replace all the lambdas by fun, e.g.:
for the church numerals: you know that zero = \f -> (\x -> x), one = \f -> (\x -> f x), so in Ocaml, you'd have
let zero = fun f -> (fun x -> x)
let succ = fun n -> (fun f -> (fun x -> f (n f x)))
and succ zero gives you one as you expect it, i.e. fun f -> (fun x -> f x) (to highlight it, you can for instance try (succ zero) (fun s -> "s" ^ s) ("0") or (succ zero) (fun s -> s + 1) (0)).
As far as I remember, you can play with let and fun to change the evaluation strategy, but to be confirmed...
N.B.: I put all parenthesis just to make it clear, maybe some can be removed.
My task is to remove the duplicates from a list. To do that I have to first sort the list.
I have written the function that sorts the list and the one that remove the
duplicates(once they are sorted) but I don't know how to combine them.
Example:
input: [4;5;2;2;1;3;3]
output: [1;2;3;4;5]
let rec setify = function
| [] -> []
| x :: l -> insert x (setify l)
and insert elem = function
| [] -> [elem]
| x :: l -> if elem < x then elem :: x :: l
else x :: insert elem l;;
let rec rem =function
|[] -> []
| x :: []-> x :: []
| x :: y :: rest -> if x = y then rem (y :: rest)
else x :: rem (y :: rest) ;;
You want to make the function that takes a list, creates the sorted list, and deduplicates that. In other words, you want:
let task list =
let sorted_list = setify list in
rem sorted_list
It is possible to do this in arbitrarily more complicated ways, but the above is one straightforward, one-action-per-line version. Since the phrasing of the title of your question invites it, here is one of the more sophisticated ways:
(* it's possible to write a generic combinator of functions, that takes two functions f and g *)
let combine f g =
(* and returns a function *)
fun x ->
(* that maps x to f(g(x)) *)
f (g x)
(* this function is typed as:
val combine : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
*)
(* the task can then be expressed as the combination of setify and rem: *)
let task = combine rem setify
Don't use this style unless something is actually gained from it. Most of
the times it only makes programs less readable and slower with no corresponding benefit. *)
I'm attempting to create a new list of all the unique items from another list. My in_list function works properly and returns a value saying whether or not the value is found in the seen_list, but I can't for the life of me get this to compile.
let uniq x = match in_list x seen_list with
| true -> seen_list
| false -> seen_list#[x]
| _ -> seen_list
;;
List.iter uniq check_list;;
The problem is some sort of type error. Here it is:
Error: This expression has type int -> int list
but an expression was expected of type int -> unit
Type int list is not compatible with type unit
In essence you want to take the result returned by uniq and pass it as the list for the next call of uniq. To do this, you need to use a fold, or write your own recursion. The purpose of List.iter is just to call an imperative function for each element of a list. It doesn't combine the answers in any way. That's why you're getting a type error—your function isn't imperative. I.e., it doesn't return unit.
Perhaps this is what you want:
let rec uniq_list lst =
match lst with
| [] -> []
| x :: xs ->
let r = uniq_list xs in
if in_list x r then r else x :: r
Or, using List.fold_right (equivalent to the recursive function above):
let uniq_list lst =
List.fold_right
(fun x r -> if in_list x r then r else x :: r)
lst
[]
Or using List.fold_left which is tail-recursive:
let uniq_list lst =
List.fold_left
(fun r x -> if in_list x r then r else x :: r)
[]
lst
By the way, your in_list is equivalent to the standard library function List.mem.
So I have this exercise:
filter (fun x -> x = 0) [(1,0);(2,1);(3,0);(4,1)];;
result int list [1;3]
So basically you have to match your x in fun with the second number in list and if its the same you create new list with the first number.
My solution but is wrong
let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [];;
I get the following error when i want to try the code:
Error: This expression has type int but an expression was expected of
type
int -> bool
I can't reproduce the problem you report. Here's what I see when I try your code:
$ ocaml
OCaml version 4.02.1
# let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [] ;;
val filter : 'a -> ('b * 'a) list -> 'b list = <fun>
# filter 0 [(1,0); (2,1); (3,0)];;
- : int list = [1]
There are no errors, but it gets the wrong answer. That's what I would expect looking at your code.
The error that you are getting is saying that somewhere the compiler is expecting an int -> bool function, but you are giving it an int. The reason you get this error is because you have an equality (f = snd x), where f is of type int -> bool and snd x is of type int. both arguments given to the equality must be of the same type. Instead, what you want to do is simply branch on the result of applying f to the second element of x, such as:
let rec filter f = function
| []->[]
| x::l -> if f (snd x) then fst x :: filter f l else [];;
That said, I would recommend using pattern matching instead of fst and snd, such as:
let rec filter f l =
match l with
| [] -> []
| (x,y)::l -> if f y then x :: filter f l else filter f l
Note that f y will return something of type bool, which will then determine which branch to take.
Altough Matts answer is right. It's good to just reuse existing functions instead of writing a special from the ground up:
[(1,0);(2,1);(3,0);(4,1)]
|> List.filter (fun (_, x) -> x = 0)
|> List.map fst