Could someone please explain to me what is going on in these three bindings?
What is the significance of the parens? What is the meaning of g and why does it have to be a g as an argument in the anonymous function? And overall what is actually happening in all of this... Thank you!
val a = fn g => (fn x => fn y => x) (g 0) (g 7);
val b = fn g => (fn x => fn y => x) (g 0) (g "happy");
val c = fn g => (fn x => fn y => x) (g 0) (g (g 7));
The function (fn x => fn y => x) is the constant function. It takes two arguments (x and y) and always returns the first argument (i.e. x).
This function is applied to two arguments in all three functions a, b and c:
In a the constant function is applied to (g 0) and (g 7).
In b the constant function is applied to (g 0) and (g "happy").
In c the constant function is applied to (g 0) and (g (g 7)).
In all three cases, the result is (g 0) because the second argument is discarded. Therefore, all the three functions can be simplified to:
val a = fn g => g 0
val b = fn g => g 0
val c = fn g => g 0
Actually, the second function (i.e. b) raises a type error because g is first applied to an int and later applied to a string.
Although the functions a and c have the same result yet they do not have the same type:
The type of a is (int -> 'a) -> 'a because we don't know the return type of the function g. Hence, it is a polymorphic function and it's more general than c.
The type of c is (int -> int) -> int because g is applied to its own result (i.e. g is applied to (g 7)). Hence, its return type must be the same as its argument type (i.e. int).
Therefore, a is more general than c and every instance of c can be safely replaced with a but not vice versa.
Related
Is there any way to do something like a(b(c(5))) from a variable that contains the functions?
The code would be something like that:
val a = fn x => x + 10
val b = fn x => x * x
val c = fn x => (x - 2) * 3
val fs = [a, b, c]
You can apply op to the composition operator o so that it can be used as a function, and then use that function with foldr to fold the list of functions down to a single function. Use the identity function as an initial value.
Thus, foldr (op o) identity [a, b, c] is equivalent to a o (b o (c o identity)), where identity is the identity function:
fun identity x = x;
Using the posted definitions for a, b, c, and fs it's not too bad to write OP example as a one-liner:
- (foldr (op o) (fn x => x) fs) 5;
val it = 91 : int
- a(b(c 5));
val it = 91 : int
It's a bit easier if identity has been defined, but even nicer to define a higher-order function to abstract this away:
fun composeList fs = foldr (op o) (fn x => x) fs;
- composeList fs 5;
val it = 91 : int
I have just started learning F*, going through the tutorial. One of the exercises there is to prove that the reverse function on lists is injective.
Since this follows from the fact that involutions are injective I would like to express that fact as a lemma in F*. To do that I define
let is_involutive f = forall x. (f (f x) == x)
let is_injective f = forall x y. (f x == f y) ==> x == y
Is this the right way to define the notion of f being involutive or injective in F*?
Then I state the lemma
val inv_is_inj: #a:eqtype -> a -> f:(a->a) ->
Lemma (requires (is_involutive f)) (ensures(is_injective f))
Informally the proof can be written as
{ fix (x:a) (y:a)
assume (f x == f y)
then have (f (f x) == f (f y))
with (is_involutive f) have (x == y)
} hence (forall (x:a) (y:a). f x == f y ==> x == y)
then have (is_injective f)
How do I express such proof in F*?
In general, what F* language constructs can be used to prove statements of the form forall (x:a). phi x, where phi is a predicate on a type a?
I'm trying to understand the Y combinator in OCaml. I took some code from here, and I'm trying to use it to write the Ackermann function. In the examples in the link, the functions only require one argument. The Ackermann function requires two arguments, and I keep having syntax errors because of it. The code I have so far is
type 'a mu = Roll of ('a mu -> 'a);;
let unroll (Roll x) = x;;
let fix f = (fun x a -> f (unroll x x) a) (Roll (fun x a -> f (unroll x x) a));;
let acker f = function
0, n -> n + 1
| m, 0 -> f (m-1) 1
| m, n -> f (m-1) (f m (n-1))
;;
print_int (fix (acker 2 2));;
What do I need to do to get it to work? Thanks.
You are mixing curried with uncurried function definitions.
Here is acker in a consistently uncurried form:
let acker f = function
0, n -> n + 1
| m, 0 -> f (m - 1, 1)
| m, n -> f (m - 1, f (m, n - 1));;
Here is a call:
# fix acker (2, 2);;
- : int = 7
#
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'm confused about let polymorphism in OCaml.
Consider the following code:
A:
let f = (fun v -> v) in
((f 3), (f true))
B:
let f = (fun v -> v) in
((fun g ->
let f = g in
f) f)
C:
let f = (fun v -> v) in
((fun g ->
let f = g in
((f 3), (f true))) f)
For A and B, there is no problem. But for C, OCaml reports error:
Error: This expression has type bool but an expression was expected of type
int
So for A, when evaluating ((f 3), (f true)), f's type is 'a -> 'a,
for B, when evaluating let f = g in f, f's type is 'a -> 'a.
But for C, when evaluating ((f 3), (f true)), f's type is int -> int.
Why C's f doesn't have type 'a -> 'a?
I have difficulty in understanding the implementation of OCaml's
let polymorphism, I'll appreciate it a lot if anyone can give a concise
description of it with respect to the question.
Your code is unnecessarily confusing because you're using the same name f for two different things in B and also two different things in C.
Inside C you have this function:
fun g -> let f = g in (f 3, f true)
Again this is unnecessarily complicated; it's the same as:
fun g -> (g 3, g true)
The reason this isn't allowed is that it only works if g is a polymorphic function. This requires rank 2 polymorphism, i.e., it requires the ability to define function parameters that are polymorphic.
I'm not exactly sure what you're trying to do, but you can have a record type whose field is a polymorphic function. You can then use this record type to define something like your function:
# type r = { f : 'a . 'a -> 'a };;
type r = { f : 'a. 'a -> 'a; }
# (fun { f = g } -> (g 3, g true)) { f = fun x -> x };;
- : int * bool = (3, true)
# let myfun { f = g } = (g 3, g true);;
val myfun : r -> int * bool = <fun>
# myfun { f = fun x -> x };;
- : int * bool = (3, true)
The downside is that you need to pack and unpack your polymorphic function.
As a side comment, your example doesn't seem very compelling, because the number of functions of type 'a -> 'a is quite limited.