Need help understanding currying - sml

Here is an example I picked up from this ebook (http://www.cs.cornell.edu/riccardo/prog-smlnj/notes-011001.pdf)
-fun curry (f:'a * 'b -> 'c) = fn (x:'a) => fn (y:'b) => f (x,y);
val curry = fn : ('a * 'b -> 'c) -> 'a -> 'b -> 'c
How do I interpret this function. Curry takes as argument a function f of type 'a * 'b -> 'c. I can't understand the part after '='. What is the associativity order?
Here is another example:
fun add’ (x:int) (y:int):int = x + y;
How is this parsed?
Wikipedia says "currying is the technique of transforming a function that takes multiple arguments (or an n-tuple of arguments) in such a way that it can be called as a chain of functions each with a single argument (partial application)". Which is the single argument: the first or the last one out of the multiple arguments?

fn (x:'a) => fn (y:'b) => f (x,y) is parsed as fn (x:'a) => (fn (y:'b) => f (x,y)). So you have a function, which takes an argument x of type a and returns another function, which takes an argument y of type b. This other function then returns the result of calling f (x,y).
fun foo x y = ... is syntactic sugar for val foo = fn x => fn y => ..., so again foo is a function, which takes one argument x and returns another function, which takes one argument y.
Similarly the call foo 1 2 will be parsed as (foo 1) 2, i.e. it calls the function foo with the argument 1 and then calls the resulting function with the argument 2.

Related

What does f: 'a -> b' -> c' -> d' mean in ocaml?

If I have a function f defined as
f: 'a -> 'b -> c' -> d'
Does that mean it takes one argument? Or 3? And then it outputs one argument? How would I use or call such a function?
As Glennsl notes in the comments, it means both.
Very briefly, and by no means comprehensively, from an academic perspective, no function in OCaml takes more than one argument or returns more or less than one value. For instance, a function that takes a single argument and adds 1 to it.
fun x -> x + 1
We can give that function a name in one of two ways:
let inc = fun x -> x + 1
Or:
let inc x = x + 1
Either way, inc has the type int -> int which indicates that it takes an int and returns an int value.
Now, if we want to add two ints, well, functions only take one argument... But functions are first class things, which means a function can create and return another function.
let add =
fun x ->
fun y -> x + y
Now add is a function that takes an argument x and returns a function that takes an argument y and returns the sum of x and y.
We could use a similar method to define a function that adds three ints.
let add3 =
fun a ->
fun b ->
fun c -> a + b + c
The type of add would be int -> int -> int and add3 would have type int -> int -> int -> int.
Of course, OCaml is not purely an academic language, so there is convenience syntax for this.
let add3 a b c = a + b + c
Inferred types
In your question, you ask about a type 'a -> 'b -> 'c -> 'd``. The examples provided work with the concrete type int. OCaml uses type inferencing. The compiler/interpreter looks at the entire program to figure out at compile time what the types should be, without the programmer having to explicitly state them. In the examples I provided, the +operator only works on values of typeint, so the compiler _knows_ incwill have typeint -> int`.
However, if we defined an identity function:
let id x = x
There is nothing her to say what type x should have. In fact, it can be anything. But what can be determined, if that the function will have the same type for argument and return value. Since we can't put a concrete type on that, OCaml uses a placeholder type 'a.
If we created a function to build a tuple from two values:
let make_tuple x y = (x, y)
We get type 'a -> 'b -> 'a * 'b.
In conclusion
So when you ask about:
f: 'a -> 'b -> 'c -> 'd
This is a function f that takes three arguments of types 'a, 'b, and 'c and returns a value of type 'd.

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)

SML type -> type -> type

I'm struggling to understand this. Problem:
I have
datatype 'a tree= Leaf of 'a | Node of 'a tree * 'a * 'a tree
I have to find value in it using binary search. Here's my code.
fun binSearch ((Leaf n), x) = if n=x then true else false
| binSearch ((Node (left, n, right)), x) =
if n=x then true else
if n>x then binSearch (left, x) else
binSearch (right, x)
But I'm supposed to write function with this signature:
val binSearch : int tree -> int -> bool
I get the int tree * int -> bool part, but how do I do 'a -> 'b -> 'c
To turn a function of type a * b -> c into a function of type a -> b -> c, replace fun f (x, y) = ... with fun f x y = ....
fun f (x, y) = ... defines a function that takes a tuple and automatically unpacks the tuple's values into the variables x and y. This is a syntactic short cut for fun f tuple = case tuple of (x, y) => .... It leads to the type a * b -> c because a * b means "a tuple containing an a and a b". The function can then be called as f (x, y) or f t where t is a tuple.
fun f x y = ... on the other hand defines a so-called curried function, which is a function that takes the parameter x and then returns another function, which takes the parameter y and then returns the result. It is a syntactic shortcut for fun f x = fn y => .... The function can then be called as f x y or g y where g has previously been set to f x.
The signature int tree * int -> bool means that the function takes a pair (int tree, int) as input and outputs a bool.
The signature int tree -> int -> bool is equivalent to int tree -> (int -> bool), and means that the function takes an int tree and outputs a function with signature int -> bool.
Signature 'a * 'b -> 'c is obtained this way:
fun my_fun (a,b) = some_c
while signature 'a -> 'b -> 'c is obtained this way:
fun my_fun a = fn b => some_c
That is, you have to create and return a lambda expression (an anonymous function created on the fly).
Also, remember that the first kind of function is called this way: my_fun(my_tree,my_int), while the second kind this other way: my_fun my_tree my_int.

Generalized list printing function in SML

I have to write a function to print a list in SML with the following type signature :
val printGenList = fn : ('a -> 'b) -> 'a list -> unit
The "printGenList" will take two arguments function f and list l and applies the function f to each element of list l recursively.
Since I am new to ML, I am not able to implement it but I tried this code which is giving the different type signature
fun printGenList = CONS(fib, fn => printGenList fib fibs);
where, fib is
fun fib a b = CONS(a, fn => fib b (a+b));
and fibs is
val fibs = fib 0 1;
What you're trying to do is impossible, ML's type system doesn't support this type of polymorphism. If you Google, there are some printf libraries for SML that show you how to approach this -- for each type t that you want to print, you'll need to define a separate t -> unit function and compose them together.
EDIT: Oh, I see, you're not looking for a function to print lists of any type, you're looking for a higher order function that applies an 'a->'b function to every element of a list... my mistake. This is what you need:
val rec printGenList =
fn (f : 'a -> 'b) =>
(fn [] => ()
| x::xs => (f(x); printGenList f xs))

ocaml function takes function as parameter and output a function

I need to find a way to combine two functions and output them as one.
I have the following code where take in a list of function ('a->'a) list then output a function ('a->'a) using the List.fold_left.
I figured out the base case, but I tried a lot of ways to combine two functions. The output should have the type ('a -> 'a) list -> ('a -> 'a).
example output:
# pipe [] 3;;
- : int = 3
# pipe [(fun x-> 2*x);(fun x -> x + 3)] 3 ;;
- : int = 9
# pipe [(fun x -> x + 3);(fun x-> 2*x)] 3;;
- : int = 12
function:
let p l =
let f acc x = fun y-> fun x->acc in (* acc & x are functions 'a->'a *)
let base = fun x->x in
List.fold_left f base l
Since you know that you have to use a left fold, you now have to solve a fairly constrained problem: given two functions of type 'a -> 'a, how do you combine them into a single function of the same type?
In practice, there is one general way of combining functions: composition. In math, this is usually written as f ∘ g where f and g are the functions. This operation produces a new function which corresponds to taking an argument, applying g to it and then applying f to the result. So if h = f ∘ g, then we can also write this as h(x) = f(g(x)).
So your function f is actually function composition. (You should really give it a better name than f.) It has to take in two functions of type 'a -> 'a and produce another function of the same type. This means it produces a function of one argument where you produce a function taking two arguments.
So you need to write a function compose (a more readable name than f) of type ('a -> 'a) -> ('a -> 'a) -> ('a -> 'a). It has to take two arguments f and g and produce a function that applies both of them to its argument.
I hope this clarifies what you need to do. Figuring out exactly how to do it in OCaml is a healthy exercise.