Functional programming function confusion - functional-programming

I'm learning functional programming and am using Ocaml, but I'm having a bit of a problem with functions.
Anyway, I have a tuple and I want to return its first value. (Very simple I know, sorry)
let bach (x,y):(float*float) = (x,y);;
val bach : float * float -> float * float = <fun>
All well and good up here.
let john (x,y):(float*float) = y;;
val john : 'a * (float * float) -> float * float = <fun>
Now this is what confuses me. Why is there a 'a there? I know that it stands for a variable with an unknown type, but I'm confused as to how changing the return value adds that there.
I am a self professed n00b in functional programming, please don't eat me :)

You were bitten by a subtle syntax mistake that is really non-obvious for beginners:
let foo x : t = bar
is not the same as
let foo (x : t) = bar
it is on the contrary equivalent to
let foo x = (bar : t)
constraining the return type of the function.
.
So you have written
let john (x, y) = (y : float * float)
The input type is a pair whose second element, y, has type float * float. But x can be of any type, so the function is polymorphic in its type, which it represents as a type variable 'a. The type of the whole function, 'a * (float * float) -> float * float, indicates that for any type 'a, you may pass a tuple of an 'a and a (float * float), and it will return a (float * float).
This is a particular case of the snd function:
let snd (x, y) = y
which has type 'a * 'b -> 'b: for any 'a and 'b, you take a pair ('a * 'b) and return a value of type 'b.

In both of your examples you are giving type-constraints for the result of the defined function, instead of its argument (as was probably intended).
Thus
let john (x, y) : (float * float) = y;;
means that the result of john (i.e., y) should be of type (float * float). Now, since in the input we have a pair consisting of x (of which nothing is known) and y (of type float * float), the final type for the input is 'a * (float * flat).
To get what you want, you could use:
let john ((x:float), (y:float)) = y;;

If you want to learn Ocaml and functional programming in general, Programming Languages course is going to be offered at Coursera again. You will learn programming language concepts by SML, Racket and Ruby and have fun assignments to apply what you learn. Highly recommended.

Related

Do pure functions have only one possible implementation?

In the image below there is a quick explanation, why pure functions appear to have only one possible implementation.I don't really get the idea because (++) : ('a -> 'b) -> ('a -> 'b) -> 'a -> 'b for example can clearly be implemented by let (++) (f: ('a -> 'b)) (g: ('a -> 'b)) x = f x orlet (++) (f: ('a -> 'b)) (g: ('a -> 'b)) x = g x
Is that image just wrong or do I miss something here?
You are right. The attached image is incorrect even without type annotations.
At first, it's important to consider what kind of "equality" on implementations is assumed here. Let's consider the following examples.
Is (##) equal to (##+)?
let ( ## ) f x = f x
let ( ##+ ) f x =
let _ = 42 in
f x
Is (|>) equal to (|>+)?
let ( |> ) x f = f x
let ( |>+ ) x f = f ## x
Is (%) equal to (%+)?
let ( % ) f g x = f (g x)
let ( %+ ) p q r = p (q r)
If (##) is not equal to (##+), then we can construct the 5th implementation of a function bool -> bool, such as (fun x -> let _ = 42 in true).
Therefore, the author of the image would have wanted to distinguish functions not by its implementation (or codes), but by some other element such as its behavior (like duck test or the equality on mathematical functions).
Still, the image is incorrect. The image claims "for pure functions that don't have any concrete type in the signature, there is only one possible implementation", but no. For example, there is no pure function 'a -> 'b. This can be shown through the Curry–Howard correspondence.
The image is wrong if you consider the counterexample you just gave. I think the author of the image didn’t consider the possibility of type annotation.
In fact if
there are no type annotations and
all the arguments are polymorphic and or function over polymorphic types,
you don’t consider the existence of polymorphic operators such as = or <>
(otherwise it is wrong since <> and = have the same type and different implementation),
then there is only one pure implementation of your function signature.
(you can probably prove that by saying the only things you can use to define that function are :
pure functions of the same type, that can be inlined, so you can ignore that
match-patterns and let, for which the image’s argument is true
cartesian product (let f a b = a, b)
function composition
infinite recursion
and maybe other things I forget, but you can make an exhaustive list
and that the combination of these used can be guessed from the output and input types.
)

how does ML finds difference between pair and arguments in a program?

for example the following code
fun swap (pr : int*bool) =
(#2 pr, #1 pr)
fun div_mod (x : int, y : int) =
(x div y, x mod y)
the above code has taking pair(Tuple) as an argument in the first swap function , and taking two integers as an argument in function div_mod ..so my doubt is how does ML know that am calling it with a pair(Tuple) and not calling it with two arguments ?
please help me . am beginner in ML programming
Thank you :)
In terms of the types themselves, both functions take one argument, which is a pair.
These two definitions are equivalent to yours:
fun swap (i: int, b: bool) = (b, i)
fun div_mod (xy: int * int) = ((#1 xy) div (#2 xy), (#1 xy) mod (#2 xy))
The only difference is whether you do pattern matching against the elements of the tuple or not.
There's a slight difference in whether you would say that a function takes one or two arguments, though.
If the pair is just "incidental" – used for grouping like in these functions – you often say that the function takes two arguments.
If the pair represents some kind of abstraction like, say, a rational number, you would probably say that it takes one argument.
I suggest you check it in your preferred SML:
str#s132-intel:~> poly
Poly/ML 5.5.2 Release
>fun swap (pr : int*bool) = (#2 pr, #1 pr);;
val swap = fn: int * bool -> bool * int
>
> fun div_mod (x : int, y : int) = (x div y, x mod y);;
val div_mod = fn: int * int -> int * int
The first takes type int * bool, the second takes int * int, both are pairs.
In contrast, multiple arguments which are not tuples:
> fun maketriple a b c = (a, b, c);;
val maketriple = fn: 'a -> 'b -> 'c -> 'a * 'b * 'c
And how does SML tell the types of arguments apart? Tuples are written inside parens and separated by commata.

F# - Treating a function like a map

Long story short, I came up with this funny function set, that takes a function, f : 'k -> 'v, a chosen value, k : 'k, a chosen result, v : 'v, uses f as the basis for a new function g : 'k -> 'v that is the exact same as f, except for that it now holds that, g k = v.
Here is the (pretty simple) F# code I wrote in order to make it:
let set : ('k -> 'v) -> 'k -> 'v -> 'k -> 'v =
fun f k v x ->
if x = k then v else f x
My questions are:
Does this function pose any problems?
I could imagine repeat use of the function, like this
let kvs : (int * int) List = ... // A very long list of random int pairs.
List.fold (fun f (k,v) -> set f k v) id kvs
would start building up a long list of functions on the heap. Is this something to be concerned about?
Is there a better way to do this, while still keeping the type?
I mean, I could do stuff like construct a type for holding the original function, f, a Map, setting key-value pairs to the map, and checking the map first, the function second, when using keys to get values, but that's not what interests me here - what interest me is having a function for "modifying" a single result for a given value, for a given function.
Potential problems:
The set-modified function leaks space if you override the same value twice:
let huge_object = ...
let small_object = ...
let f0 = set f 0 huge_object
let f1 = set f0 0 small_object
Even though it can never be the output of f1, huge_object cannot be garbage-collected until f1 can: huge_object is referenced by f0, which is in turn referenced by the f1.
The set-modified function has overhead linear in the number of set operations applied to it.
I don't know if these are actual problems for your intended application.
If you wish set to have exactly the type ('k -> 'v) -> 'k -> 'v -> 'k -> 'v then I don't see a better way(*). The obvious idea would be to have a "modification table" of functions you've already modified, then let set look up a given f in this table. But function types do not admit equality checking, so you cannot compare f to the set of functions known to your modification table.
(*) Reflection not withstanding.

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