Ocaml how to identify function - ocaml

I want to write Ocaml function, that takes two parameters: other function (int->int) and int value, and than check somehow if it was used with these to parameters earlier. how to do it?
so other way of looking at that problem is how to identify function with the identification that can be variable?
The problem is: Make function g, that takes functions f and int value n, than check if g was already used for f for that value n, if yes return previously got result, otherwise count f for n value. f is int->int

You can compare functions with the == operator.
# let f x = x + 2;;
val f : int -> int = <fun>
# let g x = x + 5;;
val g : int -> int = <fun>
# f == g;;
- : bool = false
# f == f;;
- : bool = true
#
Using the == operator is very dangerous, however. Comparing things for physical equality is inadvisable because it pierces the veil of referential transparency. I would personally look for another way to solve whatever problem you're working on. (If you'll forgive the suggestion.)

You need to flip your idea around: instead of keeping the function f and g separately, have g turn f into a memoizing version of itself:
module IntMap = Map.Make (struct type t = int let compare a b = a - b end)
let g f =
let m = ref (IntMap.empty) in
fun x ->
try IntMap.find x !m
with Not_found ->
let r = f x in
m := IntMap.add x r !m;
r
It's obviously worth doing benchmarks to see if the cost of computation is worse that the one of memoization. Also, it could be better to use a Hashtbl instead of a Map (left as an exercise).

Related

Simplify a repetitive pattern using monads

I'm actually not sure this is doable with monads or that it should be done with them and I'm looking for a solution rather than solve it with monads if monads are not the solution.
Let's say I have the following code (simplified but the idea is here):
module IM = Map.Make (Int)
let f k v m =
if IM.mem k m then (m, true)
else (IM.add k v m, false)
let a =
let m = IM.empty in
let m, res = f 0 "Zero" m in
if res then
let m, res = f 1 "One" m in
if res then f 2 "Two" m else (m, res)
else (m, res)
I'm repeating multiple times:
let value, boolean = function application to value and other values in
if boolean then another function application to the new value and other values (not the same as the first one)
else the result
This means that these functions don't necessarily have the same type but they all return a a IM.t * bool (a being the same type for every function)
I wondered if it was possible to create an inline operator that would allow me to do it.
I tried something like:
module EqMonad = struct
let ( let* ) (t, res) f2 = if res then f2 t else (t, false)
let return t = t
end
But it'll obviously not work because f2 takes more than one argument but needs to receive t as its last argument.
I guess I could summarize my problem like this:
Is it possible to have monads wrapping variadic functions?
Your solution works (with return corrected to be the monadic return) and is a restricted version of the error monad:
let return x = x, true
let a =
let m = IM.empty in
let* m = f 0 "Zero" m in
let* m = f 1 "One" m in
let* m = f 2 "Two" m in
return m
However, since the control flow never depends on the value of m, this is a sign that it might simpler to use a regular function:
let rec add_first_fresh m l = match l with
| [] -> None
| (k,v):: q ->
if IM.mem k m then add_first_fresh m q
else Some (IM.add k v m)
let a = add_first_fresh IM.empty
[0, "Zero";
1, "One";
2, "Two"
]

How can you make a function that returns a function in ocaml

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.

OCaml Function that takes in functions

I need to write a pipe function in OCaml such that pipe [f1;...;fn] (where f1,...,fn are functions!) returns a function f such that for any x, f x computes fn(...(f2(f1 x))).
I need to write it using List.fold_left and need to fill in the parameter of the function
let pipe fs =
let f a x = "fill in this part" in
let base = fun x ->x in
List.fold_left f base fs;;
I already filled in the base. If the first parameter to pipe is an empty list, it returns the second parameter. Ex: pipe [] 3 = 3.
i know for the let f a x part I want to perform function x of the accumulated functions a.
I'm just not sure how to write that. I wrote let f a x = x a but that gave me an error when i tested
pipe [(fun x -> x+x); (fun x -> x + 3)] 3
it should run x+x on 3 then run x+3 on the result and give me 9 but it gave it a type error when i tried to use let f a x = x a
for the fill in part
# let _ = pipe [(fun x -> x+x); (fun x -> x + 3)] 3;;
File "", line 1, characters 24-25:
Error: This expression has type 'a -> 'a
but an expression was expected of type int
What is the correct format to create a function that takes in 2 functions and runs them on each other. Ex: make a function that takes in functions a and b and runs b on the result of a.
To evaluate (fold_left g init fs) x:
when fs is empty, (fold_left g init fs) x = init x. In your case, you want it to be x.
when fs = fs' # [fn]: according to what you would like to be true, the expression should evaluate to
fn (fold_left g init fs' x) but using the definition of fold_left it evaluates also to (g (fold_left g init fs') fn) x.
Hence if the following equations are true:
init x = x
(g k f) x = f (k x)
the problem is solved. Hence, let us define init = fun x -> x and
g k f = fun x -> f (k x).
Well, base is a function like this fun x -> ....
Similarly, your function f needs to return a function, so assume it returns something that looks like this:
fun z -> ...
You have to figure out what this function should be doing with its argument z.
figured it out just needed that z in there for a and x to call

What does function return when "function times zero" in functional programming?

I am stuck with this SML assignment. I am trying to create a compound function (fun compound n f). It's supposed to apply the function f on itself for n times for example, compound 3 f will equal to f(f(f(x))). I got it to work except for case where n is zero. I asked the professor but he won't tell me a direct answer. He tried to give me an hint that "what's function times zero?" I still can't figure that out either. Can stackoverflow figure it out?
Thanks.
My code:
fun compound n f =
if n < 2 then
if n = 0 then fn x => f x else fn x => f x
else fn x => f(compound (n-1) f(x));
example:
val fnc = fn x => x + 1; (* example function to be used *)
compound 5 fnc(10); (* will return 15 which is correct*)
compound 0 fnc(10); (* returns 11, should be 10 *)
Answer:
fun compound n f =
if n < 2 then
if n = 0 then fn x => x else fn x => f x
else fn x => f(compound (n-1) f(x));
I won't give you the final answer because I don't like to upset teachers ;) However, I'll try a derivation that I believe you'll find easy to complete.
Let's start from a very simple case. Let's "reimplement" function application, i.e., let's write a function that takes a function and an argument and apply the first param to the second one:
fun apply f a = f a
Let's use a contrived function, that increments integers, for testing:
- fun inc n = n + 1;
val inc = fn : int -> int
- inc 1;
val it = 2 : int
- apply inc 1;
val it = 2 : int
Now, let's write apply2, a function which takes a function and an argument and applies the param function two times to the argument:
fun apply2 f a = f (f a)
Let's test it with inc:
- apply2 inc 1;
val it = 3 : int
Seems to be working. As you might expect, we'd now implement apply3, apply4 and so on. Let's see some of them at once:
fun apply f a = f a
fun apply2 f a = f (f a)
fun apply3 f a = f (f (f a))
fun apply4 f a = f (f (f (f a)))
It looks like we can rewrite later ones in terms of the earlier ones:
fun apply2 f a = f (apply f a)
fun apply3 f a = f (apply2 f a)
fun apply4 f a = f (apply3 f a)
We can even rewrite apply:
fun apply f a = f (apply0 f a)
Remember the previous definition of apply, they're equivalent:
fun apply f a = f a
So, what should apply0 be?
fun apply0 f a = ...
What is the base case for this algorithm? i.e. at what value of n does the recursion terminate? When it terminated what do you return? Think about what you would want to return if f is not applied to x. In the context of your example, if fnc is applied to 10 zero times, what should be returned?
fun compound n f =
(* If n equals the termination value, then return the base case*)
if n = ?
else fn x => f(compound (n-1) f(x));
There is a pattern here that exists in the base case for recursive algorithms. For example, what is the sum of a list with no elements? Or, what is the length of a list with no elements?

Ocaml loop function

I need to make a function that takes as inputs a function f and input b and calls f on b to return (b',c') b' is some result and c' is a boolean. The function needs to then keep calling f on b' as long as c' is true
This is what I wrote:
let rec wwhile (f,b) = match f b with
| (a,c) -> if c then wwhile(f a,c) else a
;;
the idea is I want to get the tuple result of f b and check if c is true but im not sure it using pattern matching is the best way to accomplish this. Also this function gives me a syntax error which im not sure why
heres a sample correct asnwer:
# let f x = let xx = x*x*x in (xx,xx<100);;
val f : int -> int * bool = fn
# wwhile (f,2);;
- : int = 512
figured out correct code:
let rec wwhile (f,b) = match f b with
| (a,c) -> if c then wwhile(f ,a) else a
;;