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)
Related
I noticed that I cannot do the following in OCaml:
# let foo (f : 'a -> unit) = f 1; f "s";;
Error: This expression has type string but an expression was expected of type
int
In Haskell, this could be resolved by universally quantifying the input function f using Rank2Types:
{-# LANGUAGE Rank2Types #-}
foo :: (forall a. a -> ()) -> ()
foo f = let a = f 1 in f "2"
How can I get similar exposure to this in OCaml?
OCaml only supports semi-explicit higher-rank polymorphism: polymorphic functions arguments must be boxed either inside a record with polymorphic field:
type id = { id: 'a. 'a -> 'a }
let id = { id=(fun x -> x) }
let f {id} = id 1, id "one"
or inside an object
let id' = object method id: 'a. 'a -> 'a = fun x -> x end
let f (o: <id:'a. 'a -> 'a>) = o#id 1, o#id "one"
Beyond the syntactic heaviness, this explicit boxing of polymorphic functions has the advantage that it works well with type inference while still requiring only annotations at the definition of record types or the methods.
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.
Given the following function in SML:
fun i a b = let fun j()=a+1 in j end;
The data type of the function is:
val i = fn : int -> 'a -> unit -> int
I don't understand why int -> 'a -> unit -> int?
And why not (int * a') -> unit -> int, since the function i receives two inputs.
If you defined the function as fun i (a,b) = ... then it would take a tuple as an argument and its type would indeed be (int * 'a) -> unit -> int. It would be called as i (23,42) () ((23,42) being a tuple and () being the unit value).
However you defined it as fun i a b = ..., which defines a function that takes an argument and then returns another function that takes the next argument. It is a shortcut for fun i a = fn b => .... It can be called as i a b ().
This function (as well, as any function in SML) is actually receive one input, because of currying.
Technically there is function that takes unit, that returns function that takes 'a that returns function that takes int.
So
fun foo a b = a + b;
is just an syntactic sugar to
fun foo a = fn b => a + b;
and so on.
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.
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.