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.
Related
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.
I am trying to write a function that takes 3 numbers, x y z. If x is equal to y, then it should return z. Otherwise, return x. I am having trouble figuring out why my attempt always returns z, even if x!=y. Any help would be appreciated I am still new to OCaml.
let test x y z =
match x with
| y when x = y -> z
| _ -> x
Your code doesn't compare x to y, it uses the pattern y to match against x. This always succeeds and binds y to the value of x. That is, you're creating a new local variable y that has the same value as x.
To fix your code, you could do this:
let test x y z =
match x with
| _ when x = y -> z
| _ -> x
But that seems a bit silly when you could just do:
let test x y z =
if x = y then z else x
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
Can someone explain the syntax used for when you have nested functions?
For example I have a outer and an inner recursive function.
let rec func1 list = match list with
[] -> []
|(head::tail) ->
let rec func2 list2 = match list2 with
...
;;
I have spent all day trying to figure this out and I'm getting a ever tiring "Syntax error".
You don't show enough code for the error to be obvious.
Here is a working example:
# let f x =
let g y = y * 5 in
g (x + 1);;
val f : int -> int = <fun>
# f 14;;
- : int = 75
Update
Something that might help until you're used to OCaml syntax is to use lots of extra parentheses:
let rec f y x =
match x with
| h :: t -> (
let incr v = if h = y then 1 + v else v in
incr (f y t)
)
| _ -> (
0
)
It's particularly hard to nest one match inside another without doing this sort of thing. This may be your actual problem rather than nested functions.
I have this statement:
let val x =
let val x = 5
in(fn y =>(y,x+y))
end
in
let val y=3 and z=10
in x z
end
end;
The output is :
(10,15)
I've been trying to track how this answer was produced but am getting confused. Is there a better way to write this that would help me understand what variables are being used where? Thank you!
First, some alpha-conversion:
let val fnPairOfInputAndInputPlus5 =
let val five = 5
in ( fn input => ( input, five + input ) )
end
in let val ignored = 3 and input = 10
in fnPairOfInputAndInputPlus5 input
end
end;
This code is demonstrating that when you declare a function value, unbound values in the declaring scope, such as the value five, are "enclosed" by the declaration (hence the term "closures"). Thus the function always returns a pair consisting of its input and its input plus five.
You could simplify it to
let fun f y = (y,5+y)
val y=3 and z=10
in
f z
end;
Note that the two instances of y are independent. The inner occurrence of x (which I've eliminated) is independent of the outer one (now renamed f).
Can be understood using manual evaluation with detailed explanations.
Starting with your initial expression:
let val x =
let val x = 5
in (fn y => (y,x + y))
end
in
let val y = 3 and z = 10
in x z
end
end;
Line 2,3,4 is an expression whose type is a function, as you see in the in part. It does not depends on any outer context, so it may be simplified as just fn y => (y, 5 + y), substituting x to 5, according to the binding given in let.
So you now have this:
let val x = fn y => (y, 5 + y)
in
let val y = 3 and z = 10
in x z
end
end;
After substitution of x (and removal of the let which in then now not necessary any more):
let val y = 3 and z = 10
in (fn y => (y, 5 + y)) z
end;
Note the y appearing in (y, 5 + y) are bound to the function's argument, and not to 3. There is no reference to this outer y, so its biding may be removed.
Now you have:
let z = 10
in (fn y => (y, 5 + y)) z
end;
Substituting z to 10 and removing the let which is not necessary any more, you get:
(fn y => (y, 5 + y)) 10;
This is a function application. You may evaluate it, to get:
(10, 5 + 10);
Which gives the final and constant result you noticed:
(10, 15);