I am trying to implement some graph algorithms with the OCaml language.
I've made a graph type with a two dimension array which refer to the graph I want to use
And here is my function to get the list of all the point linked to a v point :
let voisins graphe v =
let rec voisinsAux tableau i res =
if i = Array.length tableau then
res
else if v != i then
voisinsAux tableau (i + 1) (ajouter res (Array.get tableau i))
else
voisinsAux tableau (i + 1) res
in voisinsAux (Array.get graphe.matrice v) 0
;;
I guess it's not clean but I think it's OK.
The problem is when I test it, I'm getting this:
let listeVoisins = voisins g 3;;
val listeVoisins : int list -> int list = <fun>
How can I get a fun type since voisins g 3 should be an int list type expression?
Why my listeVoisins is not executed as an expression?
Functions in OCaml are curried. We have syntax that lets us work with the concept more conveniently, but a function takes a single value and returns a single value.
Of course, functions are values, so a function can return another function which in turn takes an argument and returns something. The function it can return has access to every value that was in scope when it was created. Research "closures."
Consider your code, with the inner function rewritten to reflect this:
let voisins graphe v =
let rec voisinsAux =
fun tableau ->
fun i ->
fun res ->
if i = Array.length tableau then
res
else if v != i then
voisinsAux tableau (i + 1) (ajouter res (Array.get tableau i))
else
voisinsAux tableau (i + 1) res
in voisinsAux (Array.get graphe.matrice v) 0
That is not pretty to look at, but it's functionally the same as what you wrote.
You've then only applied two arguments to voisinsAux which takes three. This means what you've gotten back is a function that takes one argument (res - apparently an int list) and then calculates the int list result you're looking for.
Related
Is it possible in F# to apply a value as though it is a function? For example:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let message = record.Message // unsweetened field access
let unsweet = record.Func 3 // unsweetened function application
let sweet = record 3 // sweetened function application
Right now, the last line doesn't compile, of course:
error FS0003: This value is not a function and cannot be applied.
Is there some sort of syntactical sweetener that would allow me to "route" function application as I see fit, while still retaining its normal unsweetened behavior as well? I'm thinking of something magic like this:
// magically apply a record as though it was a function
let () record arg =
record.Func arg
(Note: I used a record in this example, but I'd be happy with a class as well.)
The closest thing I can think of would be a custom operator using statically resolved type parameters to resolve a specific property of type FSharpFunc, then invoke the function with the supplied input parameter. Something like this:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let inline (>.>) (r: ^a) v =
let f = (^a : (member Func: FSharpFunc< ^b, ^c>) r)
f v
record >.> 3 // val it : int = 9
I wrote this ocaml function:
(* int Base.List.t -> Base.Int.t x Base.Int.t *)
let min_and_max lst =
let mmax = ref Float.neg_infinity
and mmin = ref Float.infinity in
List.iter ~f:(fun v -> let fv = Float.of_int v in
if fv > !mmax then mmax := fv
else if fv < mmin then mmin := fv)
lst;
(Int.of_float !mmin, Int.of_float !mmax)
It is supposed to return the min and max of a list of integers, but when I compile, I get this error:
File "02-exercises/24-refs/problem.ml", line 25, characters 21-23:
Error: This expression has type Base.Float.t = float
but an expression was expected of type int
The error is pointing to the first if statement in that function. I must be making a very obvious mistake, but I can't see it.
Solution taking into account the answers and comments so far:
let min_and_max lst =
match lst with
| [] -> failwith "Cannot find min and max of empty list"
| v::[] -> (v,v)
| a::b::rest ->
let mmax = ref (max a b)
and mmin = ref (min a b) in
List.iter ~f:(fun v ->
if v > !mmax then mmax := v;
if v < !mmin then mmin := v)
rest;
(!mmin, !mmax)
Base disables polymorphic comparison: you need to use a local open to compare floats with > or < : Float.(fv > !mmax ).
p.s.: The gratuitous conversion to float (and the use of references) is a bit strange and non-optimal.
I don't understand how your compiler throws you that error. Your code contains several errors that it should detect before:
You make a wrong use of the label.
In the else arm, you are comparing against the ref mmin and not against its content —you missed the !—.
You confuse int_of_float function with Int.of_float, that don't exists.
In addition, the logical principle of the function isn't adequate. For example, the first value of the list will always enter in the mmax variable, because it will be greater than the negative infinity. But what if this value were the minimum?
Apart from the above, converting an integer to a float in this case is meaningless and causes precision loss and performance decrease. Nor is necessary to use refs.
This isn't a canonical way to proceed in a OCaml context. In OCaml it's important to try to find the simplest possible solution, because as soon as you start to complicate with the types, you end up being unable to solve the disaster.
I propose you a simpler solution for the problem, with the license to compose a polymorphic function, not only to integers:
let min_and_max lst =
(List.fold_left (fun a b -> if a < b then a else b) (List.hd lst) lst),
(List.fold_left (fun a b -> if a > b then a else b) (List.hd lst) lst);;
It's an elegant option and in addition it's based on terminal recursion. However, on that scheme you could redefine the functions yourself without using the predefined ones to go through the lists. You could also choose the two numbers with a single round, but it would be somewhat more complex to do.
I'm looking through some notes that my professor gave regarding the language SML and one of the functions looks like this:
fun max gt =
let fun lp curr [] = curr
| lp curr (a::l) = if gt(a,curr)
then lp a l
else lp curr l
in
lp
end
Could someone help explain what this is doing? The thing that I am most confused about is the line:
let fun lp curr [] = curr
What exactly does this mean? As far as I can tell there is a function called lp but what does the curr [] mean? Are these arguments? If so, aren't you only allowed one parameter in sml?
It means that lp is a function that takes 2 parameters, the first being curr and the second being, well, a list, which logically, may be either empty ([]) or contain at least one element ((a::l) is a pattern for a list where a is at the head, and the rest of the list is l).
If one were to translate that bit of FP code into a certain well-known imperative language, it would look like:
function lp(curr, lst) {
if (lst.length == 0) {
return curr;
} else {
var a = lst[0]; // first element
var l = lst.slice(1, lst.length); // the rest
if (gt(a, curr)) {
return lp(a, l);
} else {
return lp(curr, l)
}
}
}
Quite a mouthful, but it's a faithful translation.
Functional languages are based on the Lambda Calculus, where functions take exactly one value and return one result. While SML and other FP languages are based on this theory, it's rather inconvenient in practice, so many of these languages allow you to express passing multiple parameters to a function via what is known as Currying.
So yes, in ML functions actually take only one value, but currying lets you emulate multiple arguments.
Let's create a function called add, which adds 2 numbers:
fun add a b = a + b
should do it, but we defined 2 parameters. What's the type of add? If you take a look in the REPL, it is val add = fn : int -> int -> int. Which reads, "add is a function that takes an int and returns another function (which takes an int and returns an int)"
So we could also have defined add this way:
fun add a =
fn b => a + b
And you will see that they are alike. In fact it is safe to say that in a way,
the former is syntactic sugar for the later.
So all functions you define in ML, even those with several arguments, are actually functions with one argument, that return functions that accept the second argument and so on. It's a little hard to get used to at first but it
becomes second nature very soon.
fun add a b = a + b (* add is of type int -> int -> int *)
add 1 2 (* returns 3 as you expect *)
(* calling add with only one parameter *)
val add1 = add 1
What's add1? It is a function that will add 1 to the single argument you pass it!
add1 2 (* returns 3 *)
This is an example of partial application, where you are calling a function piecemeal,
one argument at a time, getting back each time, another function that accepts the rest
of the arguments.
Also, there's another way to give the appearance of multiple arguments: tuples:
(1, 2); (* evaluates to a tuple of (int,int) *)
fun add (a,b) = a + b;
add (1, 2) (* passing a SINGLE argument to a function that
expects only a single argument, a tuple of 2 numbers *)
In your question, lp could have also been implemented as lp (curr, someList):
fun max gt curr lst =
let fun lp (curr, []) = curr
| lp (curr, (a::l)) = if gt(a,curr) then lp (a, l)
else lp (curr, l)
in
lp (curr, lst)
end
Note that in this case, we have to declare max as max gt curr lst!
In the code you posted, lp was clearly implemented with currying. And the type of
max itself was fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a. Taking that apart:
('a * 'a -> bool) -> (* passed to 'max' as 'gt' *)
'a -> (* passed to 'lp' as 'curr' *)
'a list -> (* passed to 'lp' as 'someList' *)
'a (* what 'lp' returns (same as what 'max' itself returns) *)
Note the type of gt, the first argument to max: fn : (('a * 'a) -> bool) - it is a function of one argument ('a * 'a), a tuple of two 'a's and it returns an 'a. So no currying here.
Which to use is a matter of both taste, convention and practical considerations.
Hope this helps.
Just to clarify a bit on currying, from Faiz's excellent answer.
As previously stated SML only allows functions to take 1 argument. The reason for this is because a function fun foo x = x is actually a derived form of (syntactic sugar) val rec foo = fn x => x. Well actually this is not entirely true, but lets keep it simple for a second
Now take for example this power function. Here we declare the function to "take two arguments"
fun pow n 0 = 1
| pow n k = n * pow n (k-1)
As stated above, fun ... was a derived form and thus the equivalent form of the power function is
val rec pow = fn n => fn k => ...
As you might see here, we have a problem expressing the two different pattern matches of the original function declaration, and thus we can't keep it "simple" anymore and the real equivalent form of a fun declaration is
val rec pow = fn n => fn k =>
case (n, k) of
(n, 0) => 1
| (n, k) => n * pow n (k-1)
For the sake of completeness, cases is actually also a derived form, with anonymous functions as the equivalent form
val rec pow = fn n => fn k =>
(fn (n,0) => 1
| (n,k) => n * pow n (k-1)) (n,k)
Note that (n,k) is applied directly to the inner most anonymous function.
here's the problem. I need to time a function in f# using another function. I have this piece of code
let time f a =
let start = System.DateTime.Now in
let res = (fun f a -> f(a)) in
let finish = System.DateTime.Now in
(res, finish - start)
which I'm trying to call saying
time ackermann (2,9);;
I have a function ackermann that takes a tuple (s,n) as argument
Probably something fundamentally wrong with this but I don't think I'm far away from a solution that could and looks somewhat like this.
Any suggestions?
Oh btw. the error message I'm getting is saying :
stdin(19,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : (('_a -> '_b) -> '_a -> '_b) * System.TimeSpan
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
You have at least two issues:
Try let res = f a. You already have values f and a in scope, but you're currently defining res as a function which takes a new f and applies it to a new a.
Don't use DateTimes (which are appropriate for representing dates and times, but not short durations). Instead, you should be using a System.Diagnostics.Stopwatch.
You can do something like this:
let time f =
let sw = System.Diagnostics.Stopwatch.StartNew()
let r = f()
sw.Stop()
printfn "%O" sw.Elapsed
r
Usage
time (fun () -> System.Threading.Thread.Sleep(100))
I usually keep the following in my code files when sending a bunch of stuff to fsi.
#if INTERACTIVE
#time "on"
#endif
That turns on fsi's built-in timing, which provides more than just execution time:
Real: 00:00:00.099, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
I would do it like this:
let time f = fun a ->
let start = System.DateTime.Now
let res = f a
(res, System.DateTime.Now - start)
You can then use it to create timed functions e.g.
let timedAckermann = time ackermann
let (res, period) = timedAckermann (2,9)
You should also consider using System.Diagnostics.Stopwatch for timing instead of DateTimes.
As was already suggested, you should use Stopwatch instead of DateTime for this kind of timing analyses.
What wasn't mentioned yet is that if you for some reason need to use DateTime, then always consider using DateTime.UtcNow rather than DateTime.Now. The implementation of DateTime.Now can be paraphrased as "DateTime.UtcNow.ToLocalTime()", and that "ToLocalTime()" part is doing more than you might think it would do. In addition to having less overhead, DateTime.UtcNow also avoids headaches related to daylight savings time. You can find several articles and blog posts on the web on the differences between DateTime.Now and DateTime.UtcNow
Inspired by how FSharp Interactive does it (see https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/fsi/fsi.fs#L175), this will time the function plus report how much CPU, allocation, etc.
Example output: Real: 00:00:00.2592820, CPU: 00:00:26.1814902, GC gen0: 30, gen1: 1, gen2: 0
let time f =
let ptime = System.Diagnostics.Process.GetCurrentProcess()
let numGC = System.GC.MaxGeneration
let startTotal = ptime.TotalProcessorTime
let startGC = [| for i in 0 .. numGC -> System.GC.CollectionCount(i) |]
let stopwatch = System.Diagnostics.Stopwatch.StartNew()
let res = f ()
stopwatch.Stop()
let total = ptime.TotalProcessorTime - startTotal
let spanGC = [ for i in 0 .. numGC-> System.GC.CollectionCount(i) - startGC.[i] ]
let elapsed = stopwatch.Elapsed
printfn "Real: %A, CPU: %A, GC %s" elapsed total ( spanGC |> List.mapi (sprintf "gen%i: %i") |> String.concat ", ")
res
"Write a function lv: cfg -> (blabel -> ide set), which computes the live variables analysis on the given control flow graph."
Having cfg and blabel defined and ide set as a list of string, how can I create a function with that signature?
You're presumably familiar with the let syntax to define a function:
let f x = x + 1 in …
You can use this syntax anywhere, including in a function body. Now if you happen to use the inner function's name as the return value of the outer function, the outer function will be returning a function.
let outer_function x =
let inner_function y = x + y in
inner_function
The let syntax is in fact syntactic sugar for fun or function. In particular, if you define inner_function just to use the name once, you might as well use the fun notation and not bother giving the inner function a name.
let outer_function x =
fun y -> x + y
Furthermore, if all the outer function does when you pass it an argument is to build and return an inner function, then consider its behavior when you pass that function two arguments. First the outer function builds an inner function, using its first (and only) argument; then that inner function is applied to the second argument, so its body is executed. This is equivalent to having just one function that takes two arguments. This
observation is known as currying.
let outer_function x y = x + y
Note that the type of this function is int -> int -> int; this is the same type as int -> (int -> int) (the arrow type operator is right-associative).
Currying doesn't apply when the outer function does some work before building the inner function. In that case, the work is performed after receiving the first argument.
let outer_function x =
print_endline "outer";
fun y -> print_endline "inner"; x + y
So the structure of your code is likely to look like this:
let lv (c : cfg) : blabel -> ide set =
let c' = do_some_precomputation c in
fun (bl : blabel) -> (… : ide set)