OCaml Understanding Functions and Partial Applications - functional-programming

I am writing a form of form of transform in OCaml that takes in a function and also accepts a list to transform. I understand something is wrong with my pattern matching in terms of type-checking, as it will not compile and claims the types do not match but I am not sure what exactly is wrong with my cases.
I receive an actual declaration error underlining the name of the function when I attempt to compile.
let rec convert (fun: 'b -> 'c option) (l: 'b list) : 'c list =
begin match l with
| [] -> []
| h::tl -> if f h = Some h then h :: convert f tl
else convert f tl
end
I wrote the following test, which should pass in order to ensure the function works properly.
let test () : bool =
let f = func x -> if x > 3 then Some (x + 1) else None in
convert f [-1; 3; 4] = [5]
;; run_test "Add one" test
I am pretty confident the error is somewhere in my second pattern match.

You should provide the exact error message in the future when asking about a compilation error (as well as the position the compiler complains about).
In h :: convert f tl, convert f tl is 'c list, but h is 'b, so you can't combine them like this. Neither does f h = Some h make sense: f h is 'c option and Some h is 'b option. You probably want to match f h instead:
| h::tl -> match f h with
| Some h1 -> ...
| None -> ...

Related

Does a non terminating function have a type?

Consider for example let f x = f x in f 1. Is its signature defined?
If so, what is it?
One could argue, that OCaml doesn't know about the fact that it's not terminating and that its type is simply inferred as 'a. Is that correct?
let a b = let rec f x = f x in f 1;;
is for example val a : 'a -> 'b eventhough it is very clear, that when a is applied, there won't be a 'b
Then requirement for a sound type system when you have type(E) = T is that if E evaluates to some value v, then v is a value that belongs to type T. A type is meaningful when the expression gives a value, and exceptions and infinite loops do not.
The type checker however is total, and gives a type for all expression, even if it is just a free type variable.
Here the return type is left unbound, and is printed as 'a.
# let f x = if x then (failwith "A") else (failwith "B");;
val f : bool -> 'a = <fun>
Here the return type of the then branch is unified with the type of the else branch:
# let f x = if x then (failwith "A") else 5;;
val f : bool -> int = <fun>
#
One way to read function types like unit -> 'a is to remember that the
type variable 'a encompasses empty types.
For example, if I have a function f
let rec f:'a. _ -> 'a = fun () -> f ()
and an empty type
type empty = |
(* using 4.07 empty variants *)
(* or *)
type (_,_) eq = Refl: ('a,'a) eq
type empty = (float,int) eq
then I can restrict the type of f to unit -> empty:
let g: unit -> empty = f
Moreover, the more general type of f can be useful in presence of branches.
For instance, I could define a return that raises an exception in order
to exit early from a for-loop:
let search pred n =
let exception Return of int in
let return: 'a. int -> 'a = fun n -> raise (Return n) in
try
for i = 0 to n do
if pred i then return i
done;
None
with Return n -> Some n
Here, the polymorphic type of return makes it possible to use it in a context
where unit was expected.

Recursion in F#, expected type int but got type "int list -> int"

I'm new to F# and want to implement a least common multiple function of a list by doing it recursively, e.g. lcm(a,b,c) = lcm(a, lcm(b,c)), where lcm of two elements is calculated from the gcd.
I have the following code. I try to match the input of the lcm function with a list of two elements, and otherwise a general list, which I split up into its first element and the remaining part. The part "lcm (tail)" gives a compiler error. It says it was expected to have type "int" but has type "int list -> int". It looks like it says that the expression "lcm tail" is itself a function, which I don't understand. Why is it not an int?
let rec gcd a b =
if b = 0
then abs a
else gcd b (a % b)
let lcmSimple a b = a*b/(gcd a b)
let rec lcm list = function
| [a;b] -> lcmSimple a b
| head::tail -> lcmSimple (head) (lcm (tail))
Best regards.
When defining the function as let f = function | ..., the argument to the function is implicit, as it is interpreted as let f x = match x with | ....
Thus let rec lcm list = function |... is a function of two variables, which are list and the implicit variable. This is why the compiler claims that lcm tail is a function - only one variable has been passed, where it expected two. A better version of the code is
let rec gcd a b =
if b = 0
then abs a
else gcd b (a % b)
let lcmSimple a b = a*b/(gcd a b)
let rec lcm = function
| [a;b] -> lcmSimple a b
| head::tail -> lcmSimple (head) (lcm (tail))
| [] -> 1
where the last case has been included to complete the pattern.

Converting a binary tree to a list using fold function in Ocaml

Given:
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree
Use:
let rec tree_fold f e t = match t with
| Empty -> e
| Node (x, l, r) -> f x (tree_fold f e l) (tree_fold f e r);;
to convert a binary tree to a list.
Example.
let someTree = Node (1,Node(2,Node(3,Empty,Empty),Empty),Empty)
tree2list someTree gives [1;2;3].
My attempt:
let tree2list tr = match tr with
| Empty -> Empty
| Node (x,l,r) -> (tree_fold (fun acc tree-> tree::acc) [] tr)
It gives the error:
This expression has type 'a list but an expression was expected of type 'b -> 'b .
I've been at this for hours and keep getting similar errors. Any help would be very appreciated, even just a small hint would be great.
Thanks.
function that you should pass to a tree_fold accepts three arguments, and you're passing a function that can take only two arguments. That's what compiler tries to say. Of course, ther're some other problems, but I hope tha you'll cope with them!

Is it possible to make this fully polymorphic in OCaml?

in OCaml
let nth_diff_type i (x, y, z) =
match i with
1 -> x
|2 -> y
|3 -> z
|_ -> raise (Invalid_argument "nth")
So the current type is int->('a,'a,'a)->'a, right?
It implies that x, y, z must have the same type.
So my question is that is it possible to give it maximum polymorphic, so that x, y, z don't need to have the same type?
No, it isn't.
A function in OCaml should have only one return type. You can have different argument types if your return type is unique:
let nth_diff_type i (x, y, z) =
match i with
| 1 -> `Fst x
| 2 -> `Snd y
| 3 -> `Thd z
|_ -> raise (Invalid_argument "nth")
// val nth_diff_type :
// int -> 'a * 'b * 'c -> [> `Fst of 'a | `Snd of 'b | `Thd of 'c ] = <fun>
If you would like to create a few utility functions for triplets, unfortunately you have to define them separately:
let fst3 (x, _, _) = x
let snd3 (_, y, _) = y
let thd3 (_, _, z) = z
If your function were to apply an arbitrary function f to an arbitrary element of a tuple such as the function f has the right type, then you could make this polymorphic to some extend.
In other words, if you think about what you may do with your function, you'll come up with the conclusion that you will need a function of the right type to apply it to the result of nth_diff_type, whatever that type may be.
If we suppose for an instant that nth_diff_type works with any tuple, its result is potentially any type. You might get an int, a string, or instances of more complex datatypes. Let's call that type t. Then what can you do with a value of type t? You may only pass it to a function which accepts values of t.
So the problem now is to select the proper function, and that selection certainly will be done on very similar criteria than the rank of the element within your tuple. If it is so, why not simply pass your tuple, and a tuple of the functions which could be applied to nth_diff_type , and let it do the application by itself?
let nth_diff_type i (a,b,c) (fa,fb,fc) =
match i with
| 1 -> fa a
| 2 -> fb b
| 3 -> fc c
| _ -> failwith "out of range"
-: val nth_diff_type : int -> ( 'a * 'b * 'c) -> (('a -> 'd) * ('b -> 'd) * ('c -> 'd)) -> 'd
The code is already fully-polymorphic in non-dependent type systems. You could move to a dependent type system (but you probably don't want, because of the complexity costs), where the type would be something like:
(n : int) -> (a * b * c) -> (match n with 1 -> a | 2 -> b | 3 -> c | _ -> Error)
Besides pad suggestion, you may also want to use a record or object type to have a direct "out projection" operation instead of having to define it by pattern-matching first.
type ('a, 'b, 'c) triple = { nth1 : 'a; nth2 : 'b; nth3 : 'c }
(* replace *) nth_diff_type 2 v (* by *) v.nth2
With an object type (which adds a structural flavor of not having to define the type beforehand)
(* replace *) nth_diff_type 2 v (* by *) v#nth2
Note that these replacement only work with constant integers (because otherwise you need an integer->type dependency). You could work out something with GADTs and existential types to support passing the particular choice around, but you will have to pay a huge complexity cost for something that is more likely a result of not being familiar enough with the existing simple type system to understand how you really want to do things.

OCaml: Is there a function with type 'a -> 'a other than the identity function?

This isn't a homework question, by the way. It got brought up in class but my teacher couldn't think of any. Thanks.
How do you define the identity functions ? If you're only considering the syntax, there are different identity functions, which all have the correct type:
let f x = x
let f2 x = (fun y -> y) x
let f3 x = (fun y -> y) (fun y -> y) x
let f4 x = (fun y -> (fun y -> y) y) x
let f5 x = (fun y z -> z) x x
let f6 x = if false then x else x
There are even weirder functions:
let f7 x = if Random.bool() then x else x
let f8 x = if Sys.argv < 5 then x else x
If you restrict yourself to a pure subset of OCaml (which rules out f7 and f8), all the functions you can build verify an observational equation that ensures, in a sense, that what they compute is the identity : for all value f : 'a -> 'a, we have that f x = x
This equation does not depend on the specific function, it is uniquely determined by the type. There are several theorems (framed in different contexts) that formalize the informal idea that "a polymorphic function can't change a parameter of polymorphic type, only pass it around". See for example the paper of Philip Wadler, Theorems for free!.
The nice thing with those theorems is that they don't only apply to the 'a -> 'a case, which is not so interesting. You can get a theorem out of the ('a -> 'a -> bool) -> 'a list -> 'a list type of a sorting function, which says that its application commutes with the mapping of a monotonous function.
More formally, if you have any function s with such a type, then for all types u, v, functions cmp_u : u -> u -> bool, cmp_v : v -> v -> bool, f : u -> v, and list li : u list, and if cmp_u u u' implies cmp_v (f u) (f u') (f is monotonous), you have :
map f (s cmp_u li) = s cmp_v (map f li)
This is indeed true when s is exactly a sorting function, but I find it impressive to be able to prove that it is true of any function s with the same type.
Once you allow non-termination, either by diverging (looping indefinitely, as with the let rec f x = f x function given above), or by raising exceptions, of course you can have anything : you can build a function of type 'a -> 'b, and types don't mean anything anymore. Using Obj.magic : 'a -> 'b has the same effect.
There are saner ways to lose the equivalence to identity : you could work inside a non-empty environment, with predefined values accessible from the function. Consider for example the following function :
let counter = ref 0
let f x = incr counter; x
You still that the property that for all x, f x = x : if you only consider the return value, your function still behaves as the identity. But once you consider side-effects, you're not equivalent to the (side-effect-free) identity anymore : if I know counter, I can write a separating function that returns true when given this function f, and would return false for pure identity functions.
let separate g =
let before = !counter in
g ();
!counter = before + 1
If counter is hidden (for example by a module signature, or simply let f = let counter = ... in fun x -> ...), and no other function can observe it, then we again can't distinguish f and the pure identity functions. So the story is much more subtle in presence of local state.
let rec f x = f (f x)
This function never terminates, but it does have type 'a -> 'a.
If we only allow total functions, the question becomes more interesting. Without using evil tricks, it's not possible to write a total function of type 'a -> 'a, but evil tricks are fun so:
let f (x:'a):'a = Obj.magic 42
Obj.magic is an evil abomination of type 'a -> 'b which allows all kinds of shenanigans to circumvent the type system.
On second thought that one isn't total either because it will crash when used with boxed types.
So the real answer is: the identity function is the only total function of type 'a -> 'a.
Throwing an exception can also give you an 'a -> 'a type:
# let f (x:'a) : 'a = raise (Failure "aaa");;
val f : 'a -> 'a = <fun>
If you restrict yourself to a "reasonable" strongly normalizing typed λ-calculus, there is a single function of type ∀α α→α, which is the identity function. You can prove it by examining the possible normal forms of a term of this type.
Philip Wadler's 1989 article "Theorems for Free" explains how functions having polymorphic types necessarily satisfy certain theorems (e.g. a map-like function commutes with composition).
There are however some nonintuitive issues when one deals with much polymorphism. For instance, there is a standard trick for encoding inductive types and recursion with impredicative polymorphism, by representing an inductive object (e.g. a list) using its recursor function. In some cases, there are terms belonging to the type of the recursor function that are not recursor functions; there is an example in §4.3.1 of Christine Paulin's PhD thesis.

Resources