I want to calculate f(..f(x)) p times. The following is my code.
let rec function f x p = if p = 0 then x else function f (f x) p-1;;
I wonder how I should make it right.
This is very close, but your code has syntax errors that are going to make it hard to make progress. I think the main problem is that you're using function as an identifier, but it is a keyword in OCaml. If you change to myfun, things should start working quite a bit better.
You also need to watch your precedences. The following code:
f a b-1
is parsed like this:
(f a b) - 1
not like this:
f a (b - 1)
You need to write the parentheses explicitly to get this second parse.
You can define a recursive function ch to apply a function f many times (Church numeral??) as follows:
let rec ch f p x = if p = 0 then x else f (ch f (p-1) x);;
The problems in your original code are that:
need to name the function as something, such as ch here.
need to call the same function ch to get the recursion going as shown above. In your original code, there is no recursion.
Example
let p1 x = x + 1 ;;
ch p1 3 1 ;;
this will give you
- : int = 3
as intended.
Related
I'm trying to learn OCaml on my own, and I've reached imperative programming. I found this little exercise that I'm just completely stuck on how to even approach. It seems so simple, but I think my understanding is just lacking.
The problem asks me to write the function for factorial without using the rec keyword, and without loops. It's supposed to teach me the environment model, but that's also confusing to me.
My first thought was to try something like this:
let factorial =
let f = ref (fun n -> 0) in
let temp_factorial n =
if n = 0
then 1
else
begin
f := n * !f*(n-1)
!f
end
But I'm not sure if this works. Any help would be greatly appreciated :)
Your code is a little strange and wrong, but the basic idea is workable. Once you have a reference f to a function of type int -> int, you can use !f freely in later code. In fact you can assign f so it refers to a function that uses !f. This is equivalent to recursion, but it uses the imperative part of OCaml.
let f = ref (fun n -> n + 1)
f :=
(fun n ->
if n < 2 then 1
else (* ... left as an exercise ... *)
)
let factoral n = !f n
The key is that the part left as an exercise can use !f.
fun count_wcs p =
let
val count = 0
in
g (fn () => count + 1) (fn y => 1) p
end
I'm doing homework and we're not supposed to use mutations, this doesn't reassign the value to anything but it doesn't feel right. Please, don't say what is the right way to do this, because I'm supposed to figure this out.
datatype pattern = Wildcard
| Variable of string
| UnitP
| ConstP of int
| TupleP of pattern list
| ConstructorP of string * pattern
fun g f1 f2 p =
let
val r = g f1 f2
in
case p of
Wildcard => f1 ()
| Variable x => f2 x
| TupleP ps => List.foldl (fn (p,i) => (r p) + i) 0 ps
| ConstructorP(_,p) => r p
| _ => 0
end
This function g has to receive a type unit -> int function as the first argument. I checked the count after I called the function and got 0, so it is ok to write it like this, right? But still, it does feel sloppy.
Added the context (function g and the datatype used). The function count_wcs is supposed to count the number a Wildcard pattern appears in a pattern.
This does not count as a mutation, but it does resemble what you might do if you had them and is probably not going to work, depending on what it is you're doing. Mutations require references and they're made with ref and are de-referenced with !. So just stick away from those. :-)
You're doing something that will be of little benefit:
let
val count = 0
in
...
end
will bind count to 0, but will never cause count to have any other value; I presume that you want to eventually have that count increases. If it had been a reference, val count = ref 0, you could increment it by doing count := !count + 1, but since it's not, you have to make count a variable of some function for it to change.
For example:
fun count_4s ([], count) = count
| count_4s (x::xs, count) = count_4s (xs, if x = 4 then count + 1 else count)
In each call count is constant, but in each subsequent, recursive call it is possibly incremented.
This function g has to receive a type unit -> int function as first argument.
...
g (fn () => count + 1) (fn y => 1) p
...
[...] But still it does feel sloppy.
Assuming that g's first arguments have no side-effects and do not throw exceptions and do not loop forever, all they can do is return the same thing on every call. This makes them rather boring. Typically functions that either take as input or return () : unit do something else, like read or write from a source external to the program.
I wouldn't call it sloppy. Just a bit weird, without knowing the context.
It's very easy to identify mutation in standard ML - if you don't use ref variables and assign them new values with :=, it's not mutation.
And you don't, so you aren't mutating anything.
Also, your function can be simplified to
fun count_wildcards p = g (fn () => 1) (fn _ => 1) p
which makes it even clearer that nothing gets mutated.
(It's not at all clear what it's supposed to accomplish, so it's impossible to tell whether your solution is correct.)
How is it possible to composite function f n times in ML?
composite two times;f(fx)
composite three times;f(f(fx)))
composite n times; f(f(f(f.....(fx)))))))
I have tried;
fun composite f g =
let h x = f(g x)
in h end;
fun repeat f n =
if n = 0 then x
else composite f repeat(f (n - 1));
Thank you
When you write recursive functions, divide your problem into general, recursive cases, and base cases that don't require recursion. For example, composing a function with itself n times sounds like the base case might be either when n = 0 or when n = 1 (either could work; I'll get back to that).
I'd encourage pattern matching, but when recursing integers, if-then-else do seem just as simple. In any case, all the examples have been written in both styles. A simple skeleton might be:
fun repeat f n =
if n = 0
then ?
else ?
fun repeat f 0 = ?
| repeat f 1 = ?
| repeat f n = ?
On functions that return functions
I imagine some of the difficulty here is that repeat must return a function. Syntactically you can achieve that in various ways. Like John suggests, you might write it by extending repeat with x:
fun repeat f n x =
if n = 1
then f x
else ...
fun repeat f 1 x = f x
| repeat f n x = ...
to which the natural, but slightly weird, interpretation is "repeat is a function that takes three arguments; the function f, the number of times it must be applied n, and f's argument x (?!)".
Alternatively, one might also write it like
fun repeat f n =
if n = 1
then (fn x => f x)
else ...
fun repeat f 1 = (fn x => f x)
| repeat f n = ...
which might be interpreted like "repeat is a function that takes two arguments; the function f and the number of times it must be applied n, and returns a function that applies f to its argument n times."
Those definitions are really equivalent. You'll see that by translating the description into types:
val repeat : ('a -> 'a) -> int -> 'a -> 'a
val repeat : ('a -> 'a) -> int -> ('a -> 'a)
That last parenthesis is implied in the first type signature.
Sometimes it helps to think of functions with many curried arguments as "functions with many arguments", and other times it helps to think of them as "functions that return functions that take yet other arguments". And repeat seems to be a mixture of this; n is best thought of as "a second argument", but x is best thought of as "the argument that the function we're returning takes".
With this preference, and a preference for pattern matching, my recommended basis would be:
fun repeat f 0 = ...
| repeat f 1 = f
| repeat f n = ...
since (fn x => f x) and f are really one and the same function.
On the base case and the recursive case
You write:
fun repeat f n =
if n = 0 then x
else composite f repeat(f (n - 1));
The x in then x has the wrong type, since repeat f n must return a function. See above.
The case when applying f zero times is a little tricky. Whatever the result is, it should be the case that repeat f 0 should give the same result regardless of f. Or put differently, that f isn't applied, although the repeat f 0 does need to return something.
On the recursive case, really, you're just messing up the parentheses. John revealed the o operator that is Standard ML's built-in version of composite which I'll prefer, too:
composite f (repeat f (n-1))
f o repeat f (n-1)
What you need to know about parentheses in Standard ML: You add them mostly to group things. When you write composite f repeat (f (n-1)), what you're saying is: "composite is a three-argument function that takes f, repeat and f (n-1) as an argument" and "f is a function that takes integers as arguments."
When what you really wanted to say was "composite takes f and the result of composing f with itself n–1 times, and composes those." It's a classic mistake when you come from languages that expect function calls to look like foo(arg1, arg, arg3) and one thinks this translates into foo(arg1 arg arg3) when in fact you wanted foo arg1 arg2 arg3. In Standard ML, this parenthesis forces arg1 to be treated as a function and applies it to arg2 and arg3, and applies foo to the result of that. Whoops!
Your ideas are close to being correct. You could use currying to make them work:
fun composite f g x = f(g(x));
SML infers its type as:
val composite = fn : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
which is exactly right for composition. Function application is left-associative, so
composite f g x
parses as
(composite f g) x
the function definition thus reads as giving the meaning of applying the function (composite f g) to an argument x. The meaning is, of course, to return the value f(g(x)).
You can test it:
fun square x = x*x
fun increment x = x + 1
val h = composite increment square
Then e.g. h 5 evaluates to 26 as expected.
A similar tweak works for your second definition. It could begin:
fun repeat f n x =
since this seems like homework, I'll leave the details to you, but your current attempt is rather close to a correct solution.
Having said all this, you should know that composition is a built-in operator in SML, denoted by the lowercase o, and that (op o) could be used in your second definition in place of composite.
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?
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).