Im trying to make a function with this signature :
'a->'b->('a * 'b ->'b)->'b
I have tried to do a function like this :
fun f x y z = z(x,y);
but its signature is different , it is :
'a->'b->('a * 'b ->'c)->'c
How can i make it fit with the requested?
Any tip maybe?
I think the least "artificial" would be something like:
fun f x y g = g (x, g (x, y))
which ensures that g's return-type matches the type of its second parameter by calling g twice, with the result of one call being the second argument to the other.
But a simpler solution, if this isn't "cheating", is to just add an explicit type annotation:
fun f x (y : 'b) g : 'b = g (x, y)
Related
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)
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.
I have this OCaml function:
fun f [x; y; z] -> (f x y), (f z);;
and the teacher wants me to answer: what is the type of this function.
But i do not understand what does [x; y; z] means? Is it a list ? i don't think so because the solution is
('a -> 'a-> 'b) -> 'a list -> b*('a->'b))
and it means that z is of different type and I cannot undestand how do I get it. Is it a vector? a sequence of three inputs? don't think so neither because otherwise it would be
fun f x y z -> (f x y), (f z);;
Can someone help me?
Okay, let's evaluate type of fun f [x; y; z] -> (f x y), (f z) this.
Our function takes to arguments and returns a tuple. So it's type will be _ -> _ -> _ * _ where underscores are not evaluated yet parts. We will evaluate them below
Our 2nd argument is a list , so types of x , y and z are the same.
_ -> 'a list -> _ * _
when we look at 1st expression in result tuple (f x y) we see that f is applied to x and y, so we can rewrite result as:
('a -> 'a -> 'b) -> 'a list -> 'b * _
in second expression in function result expression we see f z. But we already know that f is 'a -> 'a -> 'b already, so it seems that f z has type 'a -> 'b.
('a -> 'a -> 'b) -> 'a list -> 'b * ('a -> 'b)
Et voilà!
This is a list for sure. It cannot be anything else.
Your function accepts two arguments. The first one is a function, and the second is a list, that is deconstructed into three values. The function accepts two arguments. Since all functions in OCaml is currified it can also accept one argument and "return" a function that will accept the other argument and yield a result.
So, at the end you have a pair of a result of an application of function f to the first two elements of a list, and a partial application of the same function to the third element of a list.
Hope, this answers your questions.
I'm trying to subtract two functions(both with type real) in moscow ml. It then says "Overloaded - cannot be applied to arguments of type real -> real. So how should I write the function?
fun CircleArea x = x*x*Math.pi
fun SquareArea x:real = 4*x*x
fun Area x = SquareArea - CircleArea
You probably don't actually want to subtract one function from another, but the return values of those functions once they are applied. You could achieve this in the following way:
fun Area x = (SquareArea x) - (CircleArea x)
The parentheses are not mandatory, since function application (i.e. the space between SquareArea and x) binds tighter than any binary operator, including -.
You should consider using the following naming convention in ML: Regular functions have a lowercase starting symbol, while value constructors for algebraic types have uppercase starting symbols. For example:
fun area x = squareArea x - circleArea x
But:
datatype shape = Square of int * int
| Circle of int
Subtraction of functions like we have in mathematics isn't provided as a built-in operator. You can, however, define your own.
Mathematically speaking, we define
(f - g)(x) = f(x) - g(x)
We can replicate this definition in SML as follows:
infix 5 --
fun f -- g = fn x => f x - g x
What this does is produce an operator, --, such that f -- g produces the function corresponding to fn x => f x - g x, i.e. the function that given an x calculates f x - g x.
Note, due to the type-ambiguity in the - operator, it'll default to let you subtract 'a -> int functions. In your case you'll want to subtract 'a -> real functions, so you'll need a slight modification:
infix 5 --
fun f -- g = fn x => f x - g x : real
If you use this ---operator, you will be able to define your Area function like so:
val area = squareArea -- circleArea;
(I took the liberty of making the first letter of function names lowercase, to match the SML naming conventions.)
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.