I'm a beginner of Ocaml and I want to make uncurried function curried.
for example,
let add (x,y) = x + y
It is an uncurried form and I want to make a function called "curry" like
let inc = curry(add)(1)
let ret = inc(2)
If we apply my own "curry", it can be partially applied.
Since I'm the first time in Ocaml, I just thought extract entries from the tuple in the add function(quite silly...) like
let get_1_2 (a,_) = a
let get_2_2 (_,a) = a
let curry f tp = function
f (get_1_2 tp) (get_2_2 tp)
But I know it does not make sense at all...
So How can I start?
It is sometimes easier to try a few examples before moving to the generic case. For example, in the case of the add function, you start from
let add (x,y) = x + y
and you want to go to
let add2 x y = x + y
In this case, you can see that the right hand side of the new curried function is the same that the right hand side of the old add function. You can thus rewrite the curried function as
let add2 x y = add (x,y)
If you move to multiplication, we can do the same transformation from
let mult (x,y) = x * y
to
let mult2 x y = mult (x,y)
Now if you compare our two curried function
let mult2 x y = mult (x,y)
let add2 x y = add (x,y)
The right hand side looks quite similar: they differ only by the name of the function being called on the two arguments. If we want to generalize the two function, one solution is thus to provide the function mult or add as an argument to new function. Let's call it f for now:
let f mult_or_add x y = mult_or_add(x,y)
then we can rewrite mult2 and add2 as
let mult2 x y = f mult x y
let add2 x y = f add x y
The next step is to remark that x and y appears in the same position on the right hand side and left hand side of the new definition of mult2 and add2, this mean that we can elide them
let mult2 = f mult
let add2 = f add
This means that our function f transforms a function taking a pair of arguments into a curried function that takes two arguments. In other words, f could be better called curry2:
let curry2 f x y = f (x,y)
A follow-up exercise might be to try writing a curry3 or an uncurry2 function.
Related
Is it possible to use map with a function that takes multiple arguments?
I want to use map's second and third arguments repeatedly as the function's arguments.
As in
mapF x y z = map (f y z) [1, 2, 3]
So it'll evaluate f with the same y and z values, but with x = 1, x = 2, x = 3 and so on.
You should use a lambda function, to see this works lets start by using a helper function to map f over some list.
map helper [1, 2, 3] where
helper x = f x y z
In Haskell there are two syntax for functions so lets use the lambda syntax to define our helper function:
map helper [1, 2, 3] where
helper = \x -> f x y z
using the lambda syntax we don't need to give our helper function an explicit name, it can just be an anonymous function we map over the input
map (\x -> f x y z) [1, 2, 3]
So now you can say
mapF y z = map (\x -> f x y z) [1,2,3]
But presumably you don't want x to be 1, 2 and 3, you want it to be a list
you pass as an argument to mapF. So you need to give that a different name:
mapF xs y z = map (\x -> f x y z) xs
It is Haskell convention to use s as a suffix for variables that hold lists or other containers. So if one value is x then a list of them is xs
There are guaranteed to be better ways to do this (still learning) but you can:
f' = map f [1,2,3]
f' is now a list of partially applied f
g y z= map (\h -> h y z) f'
will take each of those functions and run it on the arguments y z.
You can hack that all in one line.
the keword rec do not do anything and do not cause any segmentation fault
like this example
let rec x x=x+x in x 2;;
:-int=2
In this definition:
let rec x x = x + x
The "recursive" function name x is hidden by the parameter named x. It's just as if you had:
let rec x y = let x = y in x + x
In essence there is an inner binding that hides the recursive one.
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
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).
fun temp(x) =
let val a = x
in if a mod (x-1) = 0 then x
else temp(x-1)
end;
this is example Standard ML code.
What I want to know is that
for example user call temp(10); then a = 10 and the temp(x-1) is called.
then the variable 'a' will change to 9. Can I keep it as 10 in Standard ML?
If your function contains val a = x, then for any invocation of temp(x), the value of a will be equal to the value of x. If you want to remember the value of a from a previous invocation when you recurse, you need to pass it around as a parameter like this:
fun temp_helper x a =
if a mod (x-1) = 0 then x
else temp_helper (x-1)
fun temp x = temp_helper x x
You could also make the helper function an inner function. If you do that, you can actually remove a as a parameter and instead close over a like this:
fun temp x =
let
val a = x
fun helper x =
if a mod (x-1) = 0 then x
else helper (x-1)
in
helper x
end