In Javascript there is a pattern called the Russian doll pattern (this may also be called a 'one-shot'). Basically, it's a function that replaces itself with another at some point.
Simple example:
var func = function(){
func = function(){ console.log("subsequent calls call this...");};
console.log("first call");
}
So the first time you call func it'll output "first call" and the next (and subsequent times) it's print "subsequent calls call this...". (this would be easy to do in Scheme as well, for example)
I've been puzzling on how to do this in Ocaml?
Edit: one solution I've come up with:
let rec func = ref( fun () -> func := ( fun () -> Printf.printf("subsequent..\n"));Printf.printf("First..\n"));;
Called as:
!func () ;;
Interestingly, if I do not include the 'rec' in the definition, it never calls the subsequent function... It always prints 'First...'.
yzzlr answer is very good, but two remarks:
It forces the input of the functions to be of type unit. You can use a polymorphic version:
let doll f1 f2 =
let rec f = ref (fun x -> f := f2; f1 x) in
(fun x -> !f x);;
You can do without the hairy recursion:
let doll f1 f2 =
let f = ref f1 in
f := (fun x -> f := f2; f1 x);
(fun x -> !f x);;
(Replacing recursion with mutation is a common trick; it can actually be used to define fixpoints without using "rec")
It's pretty straightforward, but you need to use side-effects. Here's a function that takes two thunks as arguments, and returns a new thunk that calls the first thunk the first time, and the second thunk every other time.
let doll f1 f2 =
let f = ref f1 in
(fun () ->
let g = !f in
f := f2;
g ())
This isn't quite optimal, because we'll keep on overwriting the ref with the same value over and over.
Here's a slightly better version, which uses a recursive definition.
let doll f1 f2 =
let rec f = ref (fun () -> f := f2;f1 ()) in
(fun () -> !f ())
So, now, you'll get this:
# let f = doll (fun () -> 1) (fun () -> 2);;
val f : unit -> int = <fun>
# f ();;
- : int = 1
# f ();;
- : int = 2
Related
for an example, if a function receives a function as a factor and iterates it twice
func x = f(f(x))
I have totally no idea of how the code should be written
You just pass the function as a value. E.g.:
let apply_twice f x = f (f x)
should do what you expect. We can try it out by testing on the command line:
utop # apply_twice ((+) 1) 100
- : int = 102
The (+) 1 term is the function that adds one to a number (you could also write it as (fun x -> 1 + x)). Also remember that a function in OCaml does not need to be evaluated with all its parameters. If you evaluate apply_twice only with the function you receive a new function that can be evaluated on a number:
utop # let add_two = apply_twice ((+) 1) ;;
val add_two : int -> int = <fun>
utop # add_two 1000;;
- : int = 1002
To provide a better understanding: In OCaml, functions are first-class
values. Just like int is a value, 'a -> 'a -> 'a is a value (I
suppose you are familiar with function signatures). So, how do you
implement a function that returns a function? Well, let's rephrase it:
As functions = values in OCaml, we could phrase your question in three
different forms:
[1] a function that returns a function
[2] a function that returns a value
[3] a value that returns a value
Note that those are all equivalent; I just changed terms.
[2] is probably the most intuitive one for you.
First, let's look at how OCaml evaluates functions (concrete example):
let sum x y = x + y
(val sum: int -> int -> int = <fun>)
f takes in two int's and returns an int (Intuitively speaking, a
functional value is a value, that can evaluate further if you provide
values). This is the reason you can do stuff like this:
let partial_sum = sum 2
(int -> int = <fun>)
let total_sum = partial_sum 3 (equivalent to: let total_sum y = 3 + y)
(int = 5)
partial_sum is a function, that takes in only one int and returns
another int. So we already provided one argument of the function,
now one is still missing, so it's still a functional value. If that is
still not clear, look into it more. (Hint: f x = x is equivalent to
f = fun x -> x) Let's come back to your question. The simplest
function, that returns a function is the function itself:
let f x = x
(val f:'a -> 'a = <fun>)
f
('a -> 'a = <fun>)
let f x = x Calling f without arguments returns f itself. Say you
wanted to concatenate two functions, so f o g, or f(g(x)):
let g x = (* do something *)
(val g: 'a -> 'b)
let f x = (* do something *)
(val f: 'a -> 'b)
let f_g f g x = f (g x)
(val f_g: ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>)
('a -> 'b): that's f, ('c -> 'a): that's g, c: that's x.
Exercise: Think about why the particular signatures have to be like that. Because let f_g f g x = f (g x) is equivalent to let f_g = fun f -> fun g -> fun x -> f (g x), and we do not provide
the argument x, we have created a function concatenation. Play around
with providing partial arguments, look at the signature, and there
will be nothing magical about functions returning functions; or:
functions returning values.
I want to write a function prefix_action with seq (resp suffix_action), here is the code in BatEnum :
let prefix_action f t =
let full_action e =
e.count <- (fun () -> t.count());
e.next <- (fun () -> t.next ());
e.clone <- (fun () -> t.clone());
f ()
in
let rec t' =
{
count = (fun () -> full_action t'; t.count() );
next = (fun () -> full_action t'; t.next() );
clone = (fun () -> full_action t'; t.clone() );
fast = t.fast
} in t'
I want to know as we don't have clone in sequences, i want to know how i should considerate clone in these case (is it a use of the sequence) and if that's the case how can we have the number of times that the sequence is used?
Prefix_action Documentation
The sequence as it is defined don't have clone function just because it is "defined by default".
type 'a node =
| Nil
| Cons of 'a * 'a t
and 'a t = unit -> 'a node
As you can see it's just a function returning some sum type, simple value if you wish, there is no side effects (in fact they can be hiden in the body of the function, but for now let me trick you). Thus the clone function in this case is just an identity:
let clone s = s
Now if you look at the definition of enumeration you will notice little mutable keyword:
type 'a t = {
mutable count : unit -> int;
mutable next : unit -> 'a;
mutable clone : unit -> 'a t;
mutable fast : bool;
}
If we try to use same clone as for sequences, we will notice that the changes of one copy will affect the other:
# let e1 = { fast = true; (* ... *) };;
val e1 : 'a t = {fast = true; (* ... *)}
# let e2 = clone e1;;
val e2 : 'a t = {fast = true; (* ... *)}
# e1.fast <- false;;
- : unit = ()
# e2;;
'a t = {fast = false; (* ... *)}
That's why they need clone function.
So now you can implement your functions, for example prefix_action.
prefix_action f e will behave as e but guarantees that f () will be
invoked exactly once before the current first element of e is read.
The problem is in this "exactly once". I'm not sure what does it means, but let say that this means that if you pass sequence to prefix_action f and then two times to hd, then f will be executed only once (because if it means something different it's not interesting). And now we can return to this "side effects" story. Clearly, we can't implement prefix_action without them. The type of sequence doesn't contain any mutable keyword, but it contains functions! Hence, we can wrap our side effect into the function.
let prefix_action : (unit -> unit) -> 'a t -> 'a t = fun f s ->
let b = ref true in
fun () -> (if !b then f (); b := false); s ()
But now, as we have side effects, we need redefine clone. From the specification of prefix_action:
If prefix_action f e is cloned, f is invoked only once, during the
cloning.
Hence our clone:
let clone s = let _ = s (); s
fold_right gives me values starting from the tail of the list but I want to give a function to fold_right as a parameter such that this function would collect values starting from the head of the list .
I want iterto receive values starting with the head of the list.
Continous Passing is the keyword ... .Another way to ask the question would be how tofold_leftwith fold_right
let fold f ls acc = List.fold_right f ls acc
val iter : ('a -> unit) -> 'a t -> unit
let iter f my_type =
let rec iiter my_type return =
return (fold (fun x y -> f x) my_type ()) () in iiter my_type (fun x y -> ())
But when I call :
iter (fun a -> print_string a) ["hi";"how";"are";"you"];;
Output:
youarehowhi
I need
hihowareyou
This is quite simple, you must try to match the signatures for the behavior.
Iteration takes no input, and returns unit, while folding takes an input and returns an output of the same type. Now, if the input taken by folding is unit then you'll have a folding function which applies a function on each element of a collection by passing an additional unit and returning an unit, which basically corresponds to the normal iteration, eg:
# let foo = [1;2;3;4;5];;
# List.fold_left (fun _ a -> print_int a; ()) () foo;;
12345- : unit = ()
As you can see the fold function just ignores the first argument, and always returns unit.
let fold_left f init ls =
let res = List.fold_right (fun a b acc -> b (f acc a)) ls (fun a -> a)
in res init
now calling
fold_left (fun a b -> Printf.printf "%s\n" b) () ["how";"are";"you"];;
gives us
how
are
you
fold_left is like List.fold_left but constructed with List.fold_right (Not tail-recursive):
let fold_left f a l = List.fold_right (fun b a -> f a b) (List.rev l) a ;;
Is not a good idea, because fold_left is not tail-recursive and List.fold_left is tail-recursive. Is better to produce a fold_right (tail-recursive) as :
let fold_right f l a = List.fold_left (fun a b -> f b a) a (List.rev l) ;;
If you can't use List.rev :
let rev l =
let rec aux acc = function
| [] -> acc
| a::tl -> aux (a::acc) tl
in
aux [] l
;;
iter use fold_left :
let iter f op = ignore (fold_left (fun a b -> f b;a) [] op ) ;;
Test :
# fold_left (fun a b -> (int_of_string b)::a ) [] ["1";"3"];;
- : int list = [3; 1]
# rev [1;2;3];;
- : int list = [3; 2; 1]
# iter print_string ["hi";"how";"are";"you"];;
hihowareyou- : unit = ()
The continuation that you need to pass through fold in this case is a function that will, once called, iterate through the rest of the list.
EDIT: like so:
let iter f list = fold
(fun head iter_tail -> (fun () -> f head;; iter_tail ()))
list
()
I want to define a function check_char_fun: (char -> 'a) -> (char ->' a) -> bool that, given two functions
on char, return true when both functions are the same (ie, when they are exactly the same behavior on every one of the possible values of a char) and false otherwise.
let check_char_fun f1 f2 =
let aux = true
for i=0 to 255 do
if (f1 (char_of_int i))=(f2 (char_of_int i))
then aux=false;
done;
if aux=true
then true
else false;;
I am learning OCaml, so I don't know what can I do.
You're nearly there:
let check_char_fun f1 f2 =
let aux = ref true in
for i = 0 to 255 do
if (f1 (char_of_int i)) = (f2 (char_of_int i)) then aux := false
else ()
done;
!aux
Unlike the variables in imperative languages, bindings in OCaml are immutable by default. To create a real variable, we create a bool ref which is mutable and can be changed from within the loop.
OCaml does not have a distinction between statements and expressions like the imperative languages: There are only expressions! Thats why you always need the else clause to an if; this ways the resulting expression always returns a value (in both if and else case) the type of which must be the same -- in this case of type unit (the type of the value () -- which would be void in C).
Your code is not very OCaml-like, but thats what I personally love about OCaml: The functional style is not forced down your throat and you can implement algorithms in an imperative style without entering the academic ivory tower.
First, you have to have a definition for what a "behavior" is. If your functions can raise exceptions the problem gets harder. Your code assumes the functions always return a value, which seems like a good simplification for a beginning problem.
You're also using the (somewhat out-of-date) definition of character that OCaml uses, in that codes are limited to the range 0 .. 255. This also seems OK.
So the only problem I see in your code is that you're expecting to be able to change the value of the aux variable. Variables in OCaml are immutable: you can't change the value that they're bound to.
If you want to keep your code mostly as it is, you can change aux so its value is a reference to a bool. Then you can change the boolean value inside the reference (while aux remains bound to the same reference).
To make a reference to a bool and change the value:
# let x = ref true;;
val x : bool ref = {contents = true}
# !x;;
- : bool = true
# x := false;;
- : unit = ()
# !x;;
- : bool = false
(One of the reasons to study OCaml is to learn how to work with immutable values. So I'd suggest looking for other ways to solve the problem that don't require the use of references.)
let rec range i j =
if i > j then [] else i :: (range (i+1) j);;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.for_all (fun c -> (f1 c) = (f2 c)) lc;;
test:
#let id x =x;;
val id : 'a -> 'a = <fun>
# check_char_fun id id;;
- : bool = true
# check_char_fun id (fun x -> 'a');;
- : bool = false
Or:
exception Fails_in of char;;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.iter (fun c ->
if (f1 c) <> (f2 c) then raise (Fails_in c)
) lc;;
# try (
check_char_fun id id
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
- : unit = ()
# try (
check_char_fun id (fun x -> 'a')
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
Diff(0)()- : unit = ()
The following applies each function to each character value in the 0 .. 255 range and compares their results, but it does not check for cases where a function raises an exception or causes a side effect elsewhere:
open Core.Std
let check_char_fun f1 f2 =
let chars = List.map ~f:char_of_int (List.range 0 256) in
List.for_all ~f:(fun c -> (f1 c) = (f2 c)) chars
I'm not familiar with OCaml, but have been involved in analysing some OCaml code.
This piece of code puzzles me. What is the correct grouping, based on operator precedence?
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
(fmt,
fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
Buffer.reset b;
s
)
There are three operators here: ";", "," and "fun". Based on the reference manual the precedence
order is comma > semicolon > fun, which I believe leads to the following groupings below.
Which one is picked by the OCaml compiler? Or is there another grouping that is the correct one?
grouping 1:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
((fmt,
fun () ->
Format.pp_print_flush fmt ());
(let s = Buffer.contents b in
Buffer.reset b;
s)
)
grouping 2:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
(fmt,
(fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
(Buffer.reset b;
s))
)
For what it's worth, there is another operator used in the code. It's represented by no symbols: the operation of applying a function to a value in OCaml is represented by juxtaposition. This operator has higher precedence than the others.
This code
fun () -> a ; b
parses as
fun () -> (a; b)
not as
(fun () -> a) ; b
It follows because as you say ; has higher precedence than fun (though this terminology is a little suspect).
Similarly
let c = d in e; f
parses as
let c = d in (e; f)
not as
(let c = d in e); f
So, the final expression parses like this:
(fmt,
fun () -> (Format.pp_print_flush fmt ();
let s = Buffer.contents b in
(Buffer.reset b; s))
)
grouping 2 is the correct one.
If you are unsure about how things are parsed, editor helpers may help you (sometimes): ocaml-mode or tuareg-mode (and probably other editor helpers) should give you auto-indentations corresponding with how the code is parsed:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
( fmt,
fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
Buffer.reset b;
s
)
The identation of let s = ... is below fun () -> which means that that part is within fun () -> .... If it were outside of fun () -> it should be indented differently, in the same level of fun () ->.
Another, very precise but probably over complex way is to examine how the code is parsed directly by ocamlc -dparsetree source.ml.