what are curry and uncurry in high-order functions in ML - sml

fun curry f x y = f (x, y);
fun uncurry f (x, y) = f x y;
fun compose (f, g) x = f (g x);
I understand compose function, but not quite understand curry and uncurry in ML. Can anyone explain these?
Also, what do the following two lines mean?
(1) compose (compose, uncurry compose)
(2) compose (uncurry compose, compose)

If you look at the types, then you will clearly see what curry and uncurry does.
Remember that it is possible to define function which either takes its arguments as one big tuple, or as multiple arguments (in reality it becomes a "chain" of functions each taking 1 argument, see this wiki):
fun foo (a,x) = a*x+10
fun bar a x = a*x+20
The difference is clearly seen in their types:
val foo = fn : int * int -> int
val bar = fn : int -> int -> int
The curry function "transforms" a function that takes its arguments as a tuple, into a "chain" of functions that each takes 1 of the arguments. This is specifically handy when we want to compose a series of functions where some of them have been partially applied with arguments. See how the type of foo is changed:
- curry foo;
val it = fn : int -> int -> int
Now we can try and compose the two functions:
- (curry foo 5 o bar 1) 4;
val it = 130 : int
First 4 is applied to bar 1 as the argument x, then the result of that computation (bar 1 4) is given as the x argument to foo.
Obviously uncurry is used for the reverse process:
- uncurry bar;
val it = fn : int * int -> int

Related

How do we write Recursive function in SML?

Here is the python code for the recursive function I am implementing.
def f(x):
return x+1
def iter(n, f,x):
if n == 0:
return x
return iter(n-1, f, f(x))
Calling iter
iter(7, f, 9)
How do I write it in SML?
fun iter 0 f x = x
|iter n f x = iter(n-1, f, f(x));
The syntax is:
fun iter 0 f x = x
| iter n f x = iter (n-1) f (f x);
Note: you can replace f by _ at line 1 since f does not appear in the resulting expression.
OP code is mixing curried function notation with tuple notation. The OP defines a curried function, but then passes a tuple to it in the recursive call. There are two obvious solutions: decide whether curried notation or tuple notation is desired, and use that consistently.
With tuple notation iter takes a tuple containing the arguments, i.e., here iter really only takes one argument which is a data type that contains parameters. That is, tuple iter has type: fn : int * ('a -> 'a) * 'a -> 'a
fun iter (0, _, x) = x
| iter (n, f, x) = iter(n-1, f, f x);
The above could be expressed a bit differently, e.g., iter((n-1), f, (f x)), or iter((n-1), f, f(x)).
With the curried notation iter takes a single int argument and returns a function that takes a function argument, returning a function which takes an argument matching the passed function. That is, curried iter has type fn : int -> ('a -> 'a) -> 'a -> 'a.
fun iter 0 _ x = x
| iter n f x = iter (n-1) f (f x);
The tuple version and the curried version are two distinctly different situations. With the tuple version, if you pass fewer than three "arguments" you have a type error, e.g., something like:
- iter(2, double);
stdIn:1.2-1.17 Error: operator and operand do not agree [tycon mismatch]
operator domain: int * ('Z -> 'Z) * 'Z
operand: 'Y[INT] * (int -> int)
in expression:
iter (2,double)
The problem is that the tuple version expects a tuple argument that contains three fields. Passing a tuple with fewer than three fields violates this expectation.
But with the curried version, if you pass fewer than three arguments you have a partial function application:
- val doubleTwice = iter 2 double;
val doubleTwice = fn : int -> int
- doubleTwice 3;
val it = 12 : int
- doubleTwice 5;
val it = 20 : int
Here, passing only two arguments to the curried iter, one of them a double function that doubles an int, returns a function that doubles an input value twice. Curried functions can be very useful, and you need to learn the difference between these two styles.

How to pass arguments to functions that pass those arguments to other functions used as argument

I know the title is absolutely confusing but maybe this description will make it clear
I am writing a function that applies the same function to the result of itself
let add1 x = x + 1
let twice f x = (f (f x))
Now I want to write add2 using add1 and twice, so I do this
let add2 = twice add1
let%test "Testing add2..." =
Int.(=) 1337 (add2 1335)
and the test pass, but then I thought since we are passing the int value with add2 maybe another argument should be there in the function signature of add2 and be passed to add1
so I wrote this
let add2 x = twice add1 x
and this also passes the test, which is the correct way to do it and why does this happen?
They are both correct and they both mean the same.
A third—and equivalent—way of writing your example is:
let add2 = fun x -> twice add1 x
ocaml is a functional programming language, and as such it allows you to return a function as a result of another function.
Let's consider
let add x y = x + y
add has the type int -> int -> int which is actually int -> (int -> int) that is a function taking an integer as argument, and returning a function on integers.
You can thus write add1 as follows:
let add1 = add 1
We applied add of type int -> (int -> int) to 1 : int so add 1 has type int -> int and corresponds to the function taking x and returning 1 + x.
When you apply add to two arguments x and y—namely add x y—you are actually writing
(add x) y.
In the end you manipulate functions and the function f is the function which associates f x to x or in other words fun x -> f x.
(I hope this is not too confusing.)

Which programming languages support functions that take themselves as arguments?

I'm doing an academic exercise (for personal growth). I want to find programming languages that allow you to define functions that are capable of accepting themselves (i.e., pointers to themselves) as arguments.
For example, in JavaScript:
function foo(x, y) {
if (y === 0) return;
x(x, y - 1);
}
foo(foo, 10);
The code above will execute foo() exactly 11 times before y reaches zero, causing the recursion to terminate.
I tried defining a similar function in OCaml like this:
let rec foo x y = if y < 1 then "hi" else x x (y - 1);;
But it failed with a type error:
Error: This expression has type 'a -> 'b -> 'c
but an expression was expected of type 'a
The type variable 'a occurs inside 'a -> 'b -> 'c
I'm wondering, is it possible to define such a function in OCaml? I'm particularly interested in OCaml because I know it has a global type inference system. I want to know if such functions are compatible with global type inference. Thus, I'm looking for examples of these types of functions in any language with global type inference.
It is possible in any language, that features either mutability or recursion or both, to call a function with a pointer to itself. Basically, all conventional Turing complete languages, have those features, therefore there are so many answers.
The real question is how to type such functions. Non strongly typed languages (like C/C++) or dynamically (or gradually) typed are of no interest, as they enable type coercing of some form, that basically makes the task trivial. They rely on a programmer to provide a type and take it as granted. Therefore, we should be interested in strictly typed languages with the static type system.
If we will focus on OCaml, then your definition could be accepted by the compiler if you pass the -rectypes option, which will disable the occurrence check, that disallows recursive types. Indeed, the type of your function is ('a -> int -> string as 'a) -> int -> string,
# let foo x y = if y < 1 then "hi" else x x (y - 1);;
val foo : ('a -> int -> string as 'a) -> int -> string = <fun>
Note that, you don't need rec here, as your function is not really recursive. What is recursive is the type, ('a -> int -> string as 'a), here as expands to the left up to the parenthesis, i.e., 'a = 'a -> int -> string. This is a recurrence and, by default, many compilers disallow such equations (i.e., equations where the same type variable occurs on both sides of the equation, hence the name occurrence check). If this check is disabled, the compiler will allow this and alike definitions. However, it was observed that the occurrence check catches more bugs than disallows well-formed programs. In other words, when the occurrence check is triggered it is more likely a bug, rather than a deliberate attempt to write a well-typed function.
Therefore, in real life, programmers feel reluctant to introduce this option to their build systems. The good news is that if we will massage the original definition a little bit, we don't really need recursive types. For example, we can change the definition to the following,
let foo x y = if y < 1 then "hi" else x (y - 1)
which now has type
val foo : (int -> string) -> int -> string = <fun>
I.e., it is a function that takes another function of type (int -> string) and returns a function of type (int -> string). Therefore, to run foo we need to pass it a function that recursively calls foo, e.g.
let rec run y = foo run y
This is where the recursion comes into play. Yes, we didn't pass the function to itself directly. Instead, we passed it a function, that references foo and when foo calls this function it, in fact, calls itself, via an extra reference. We may also notice, that wrapping our function in a value of some other kind1) (using, record, or variant, or object) will also allow your definition. We can even specify those extra helper type as [##unboxed] so that the compiler will not introduce extra boxing around the wrapper. But this is a sort of cheating. We still won't be passing the function to itself, but an object that contains this function (even though the compiler optimization will remove this extra indirection, from the perspective of the type system, those are still different objects, therefore the occurrence check is not triggered). So, we still need some indirection, if we don't want to enable recursive types. And let's stick to the simplest form of indirection, the run function and try to generalize this approach.
In fact, our run function is a specific case of a more general fixed-point combinator. We can parametrize run with any function of type ('a -> 'b) -> ('a -> 'b), so that it will work not only for foo:
let rec run foo y = foo (run foo) y
and in fact let's name it fix,
let rec fix f n = f (fix f) n
which has type
val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
And, we can still apply it to our foo
# fix foo 10
The Oleg Kiselyov web site is an excellent resource that shows many ways of defining the fixed point combinator in OCaml, Scheme, and Haskell.
1) This is essentially the same as the delegate approach, that was shown in other answers (both including languages with type inference like Haskell and OCaml, and languages that don't, like C++ and C#).
Your OCaml function requires a recursive type, i.e., a type that contains a direct reference to itself. You can define such types (and have values of such types) if you specify -rectypes when you run OCaml.
Here's a session with your function:
$ rlwrap ocaml -rectypes
OCaml version 4.06.1
# let rec foo x y = if y < 1 then "hi" else x x (y - 1);;
val foo : ('a -> int -> string as 'a) -> int -> string = <fun>
# foo foo 10;;
- : string = "hi"
#
The default is not to support recursive types, because they almost always are the result of programming errors.
As Jeffrey points out, OCaml can deal with this, if you activate -rectypes. And the reason that it is not turned on by default is not that it's a problem for ML-style type inference, but that it's usually not helpful to programmers (masks programming errors).
Even without the -rectypes mode you can easily construct an equivalent functions via an auxiliary type definition. For example:
type 'a rf = {f : 'a rf -> 'a}
let rec foo x y = if y < 1 then "hi" else x.f x (y - 1)
Note that this still infers everything else, such as the other function arguments. Sample use:
foo {f = foo} 11
Edit: As far as ML type inference is concerned, the only difference between the algorithm with and without -rectypes is that the latter omits the occurs-check during unification. That is, with -rectypes the inference algorithm actually becomes "simpler" in a sense. Of course, that assumes a suitable representation of types as graphs (rational trees) that allows cycles.
Some examples I can write:
C++
C
C#
Python
Scheme
C++
Ok, so not the first language you would think of, and definitely not a painless way of doing it, but it's very much possible. It's C++ and it's here because they say write about what you know :) Oh, and I wouldn't recommend doing this outside of academic interest.
#include <any>
#include <iostream>
void foo(std::any x, int y)
{
std::cout << y << std::endl;
if (y == 0)
return;
// one line, like in your example
//std::any_cast<void (*) (std::any, int)>(x)(x, y - 1);
// or, more readable:
auto f = std::any_cast<void (*) (std::any, int)>(x);
f(x, y - 1);
}
int main()
{
foo(foo, 10);
}
If the casts are too much (and too ugly) you can write a small wrapper like bellow. But the biggest advantage is performance: you completely bypass the std::any heavy type.
#include <iostream>
class Self_proxy
{
using Foo_t = void(Self_proxy, int);
Foo_t* foo;
public:
constexpr Self_proxy(Foo_t* f) : foo{f} {}
constexpr auto operator()(Self_proxy x, int y) const
{
return foo(x, y);
}
};
void foo(Self_proxy x, int y)
{
std::cout << y << std::endl;
if (y == 0)
return;
x(x, y - 1);
}
int main()
{
foo(foo, 10);
}
And a generic version of the wrapper (forwarding omitted for brevity):
#include <iostream>
template <class R, class... Args>
class Self_proxy
{
using Foo_t = R(Self_proxy<R, Args...>, Args...);
Foo_t* foo;
public:
constexpr Self_proxy(Foo_t* f) : foo{f} {}
constexpr auto operator()(Self_proxy x, Args... args) const
{
return foo(x, args...);
}
};
void foo(Self_proxy<void, int> x, int y)
{
std::cout << y << std::endl;
if (y == 0)
return;
x(x, y - 1);
}
int main()
{
foo(foo, 10);
}
C
You can do this in C also:
https://ideone.com/E1LkUW
#include <stdio.h>
typedef void(* dummy_f_type)(void);
void foo(dummy_f_type x, int y)
{
printf("%d\n", y);
if (y == 0)
return;
void (* f) (dummy_f_type, int) = (void (*) (dummy_f_type, int)) x;
f(x, y - 1);
}
int main()
{
foo((dummy_f_type)foo, 10);
}
The trap to avoid here is that you cannot use void* as the type for x as it's not valid to cast a pointer type to a data pointer type.
Or, as shown by leushenko in the comments, you can use the same pattern with a wrapper:
#include <stdio.h>
struct RF {
void (* f) (struct RF, int);
};
void foo(struct RF x, int y)
{
printf("%d\n", y);
if (y == 0)
return;
x.f(x, y - 1);
}
int main()
{
foo((struct RF) { foo }, 10);
}
C #
https://dotnetfiddle.net/XyDagc
using System;
public class Program
{
public delegate void MyDelegate (MyDelegate x, int y);
public static void Foo(MyDelegate x, int y)
{
Console.WriteLine(y);
if (y == 0)
return;
x(x, y - 1);
}
public static void Main()
{
Foo(Foo, 10);
}
}
Python
https://repl.it/repls/DearGoldenPresses
def f(x, y):
print(y)
if y == 0:
return
x(x, y - 1)
f(f, 10)
Scheme
And finally here's a functional language
https://repl.it/repls/PunyProbableKernelmode
(define (f x y)
(print y)
(if (not (= y 0)) (x x (- y 1)))
)
(f f 10)
One language that is incredible for recursion/iteration (the name for what you're asking for) is a dialect of Lisp called Scheme. Check out a book called SICP for this language. Calling self is a technique to implement anonymous recursion.
Here is what your procedure would look like in Scheme:
(define (foo x y)
(if (= y 0) null (x x (- y 1))))
(foo foo 10)
For completeness, Haskell.
newtype U a = U { app :: U a -> a }
foo :: Int -> ()
foo y = f (U f) y
where
f x y | y <= 0 = ()
| otherwise = app x x (y-1)
Trying:
> foo 10
()
The statically typed languages seem to be doing more or less the same thing to achieve this: put the function into a record and pass that to itself as an argument. Haskell's newtype creates ephemeral "records" though, so it really is the function itself, at run time.
The dynamically typed languages just pass self to self and are done with it.
You can do it in C which supports function pointers, C# which supports delegates, and Java in which you might need to declare your own #FunctionalInterface for the method to match.

How to declare an argument as a function in SML?

my question goes like this:
how can I define a function , that receives a function without using type constraints or in other words, without having to type fun f1(f2:type->type) ?
I'm trying to think of a way that uses the argument f2 as a function but its not getting anywhere.
Any ideas?
The one thing that you can do with a function that you can't do with any other value, is to call it. So using f2 as a function means calling it - that is, applying it to an argument.
So for example you could define f1 as:
fun f1 f2 = f2 42
and the inferred type of f1 would be (int -> 'a) -> 'a (making the type of f2 int -> 'a).
By returning an anonymous function, you can do this in such a way that the resulting function can take an arbitrary function for input (although not in a very useful way):
fun id f = fn x => f x
This makes id a higher-order function which returns its input function unmodified. The type of id is fn : ('a -> 'b) -> 'a -> 'b
As an example of its "use":
- fun f x = x*x;
val f = fn : int -> int
- val g = id f;
val g = fn : int -> int
- g 5;
val it = 25 : int
A slightly more interesting example which will only work with functions of type 'a -> 'a:
fun self_compose f = fn x => f (f x)

Finding max element in a list in SML

I am trying to find the the greatest value in a list using Standard ML. I need to use the given fold function:
fun fold f [] base = base
| fold f (x::xs) base = fold f xs (f x base);
Here is what i have so far:
fun max (x::xs) = fold (fn (a, b) => if a > b then a else 0) x (x::xs);
I have 0 in there because if the list is empty then I need to return 0;
This is only part of another function that I need to define, but I'm struggling with the fold part.
In your definition of the fold function, you require that the function f must take it's arguments in curry form, that is: f 1 1 instead of f(1,1).
As I understand, then your definition of the fold function is the right one. Thus you need to make proper changes to the anonymous function in the max function.
In SML, currying is actually just syntactic sugar. For example:
fun foo a b = a+b
would end up as (after desugaring):
val rec foo = fn a => fn b => a+b
It is also seen that the two functions has the same type:
- fun foo a b = a+b;
val foo = fn : int -> int -> int
- val rec foo = fn a => fn b => a+b;
val foo = fn : int -> int -> int
Thus the anonymous function must be define somewhat along the same lines.
Also you have mixed the arguments to fold. In the last part of the max function, you are giving the two last arguments in the reverse order.
The last problem is that your anonymous function returns 0. This screws with the invariant of you anonymous function and makes it fail in some cases. For example:
max [1,4,65,7,6];
Try to figure out why yourself.
If you really need to return 0 if the input list to max is empty, then you should pattern match that case. This also fixes the warning about "match nonexhaustive", and is the correct place to do it.
fun max [] = 0
| max (x::xs) = fold (fn a => fn b => if a > b then a else b) (x::xs) x;