how to time an arbitrary function in f# - 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

Related

An expression is recognized as a function

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.

Read data from MySQL via Vec<Row>

What's the best (simple, safe & efficient) way to read data from MySQL via Vec<Row>?
Here is an example function that uses a vector of (specific) tuples:
fn read_recs(tx: &mut Transaction) -> Result<HashMap<i64, String>> {
let q = format!("SELECT id, name FROM some_table");
let rows: Vec<(i64, String)> = tx.query(q)?;
let mut res = HashMap::new();
for r in rows {
res.insert(r.0, r.1);
}
Ok(res)
}
For simple queries I've found that approach good enough (as well as query_map()), but for queries returning more columns, I'd prefer to directly read into Vec<Row> and then somehow read the values in a simple (not too verbose) fashion like this:
let rows: Vec<Row> = tx.query(q)?;
for r in rows {
let id: i64 = extract(r, 0)?;
let name: String = extract(r, 1)?;
}
or maybe even this:
let rows: Vec<Row> = tx.query(q)?;
for r in rows {
let id: i64 = extract(r, "id")?;
let name: String = extract(r, "name")?;
}
Question is, what would that extract look like so that it either reads the data successfully or returns an error? I do not want it to panic in case, for example, the query returns NULL in a situation where I only expect not-null values. And obviously I would prefer not to have to deal with Option<...> values every time I read data from a field, as that would make my code way too verbose.
BTW I use Anyhow if that matters.
I don't know if I quite understand the question, but wouldn't this work?
fn extract<I, T>(row: &Row, index: I) -> anyhow::Result<T>
where
I: ColumnIndex,
T: FromValue,
{
row.get_opt(index).ok_or(ValueAlreadyTakenErrorOrSomething)?
}

Understanding "let" & "in" in ML programming

My teacher recently went over a function in ML that uses "let" & "in" but the body of the function is confusing to me as I dont understand how they work together to produce the result. The function takes a list of vegetables in your garden and replaces an original vegetable with a given substitute, so that list will print out the substitute in every location where the original element is in.This is the function
image to function code
fun replaceVegetable(orig, subt, Garden([]) = Garden([])
| replaceVegetable(orig, subt, Garden([first::rest]) =
let val Garden(newRest) =
replaceVegetable(orig, subst, Garden(rest));
in Garden((if first = orig then subst else first)::newRest)
end
| replaceVegetable(orig, subst, x) = x;
Im not worried about the last pattern "replaceVegetable(orig, subst, x) = x;", im mainly concerned about understanding the second pattern. I think I understand that Garden(newRest) is a local variable to the function and that whatever replaceVegetable(orig, subst, Garden(rest)) produces will be stored in that local variable. I dont exactly know what happens on "in Garden((if first = orig then subst else first)::newRest)" is this applying recursion so it can run through the list I give it to see where it has to replace the original with the substitute? If so, I can't exactly see how its doing that as the function as a whole is confusing for me to look at.
let, in, and end go together; in Garden((if first ... is not a "unit of language" and doesn't mean anything.
In the simpler form,
let val x = y in e end
means "in the expression 'e', 'x' has the same value as 'y'.
If the function took just a plain list, it might be easier to understand:
fun replaceVegetable(orig, subst, []) = []
| replaceVegetable(orig, subst, first::rest) =
let val newRest =
replaceVegetable(orig, subst, rest)
in (if first = orig then subst else first)::newRest
end
| replaceVegetable(orig, subst, x) = x;
The second case here is exactly the same as
| replaceVegetable(orig, subst, first::rest) =
(if first = orig then subst else first)::(replaceVegetable(orig, subst, rest))
Your function also has a pattern-matching binding instead of a plain variable binding.
let val Garden newRest = replaceVegetable(...)
in ...
end
matches on the result of the recursion and binds the "wrapped" list to newRest.
It means exactly the same as
case replaceVegetable (...) of
Garden newRest => ...

F#: Apply a value as though it is a function

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

F# assign (custom) type to a function

For all the progress I've made in F#, I still get lost in various of the constructor and deconstructor syntax.
I'm running a recursive simulation. One of the parameters is a function for the stopping condition. I have various possible stopping conditions to choose from. I make them all have the same signature. So I decide it would be nice, and educational, to lock down these functions to a custom type--so that not just any function that happens to match the signature can be sent:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
I think I'm doing this right, from tutorials, having a type name and an identical constructor name (confusing...), for a single case discriminated union. But now I can't figure out how to apply this type to an actual function:
let Condition1 lastRet nextRet i fl =
true
How do I make Condition1 be of type StoppingCondition? I bet it's trivial. But I've tried putting StoppingCondition as the first, second or last term after let, with and without parens and colons. And everything is an error.
Thanks for the patience found here.
EDIT:
I'll try to synthesize what I lean from the four answers (as of this moment), all good:
Trying to mimic this pattern:
s : string = "abc"
I was trying to write:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let condition1 lastRet nextRet i fl : StoppingCondition = // BAD
//wrong for a type alias, totally wrong for a union constructor
true
//or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
true
or other insertions of : Stopping Condition (trying to prefix it, in the way that constructors go, in that one line).
Now I see that to get what I was getting at I would have to do:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl = //...
true
let stoppingCondition1 = StoppingCondition conditionFunc1
//or
let stoppingCondition2 = StoppingCondition <| (func lastRet nextRet i fl -> false)
//and there's another variation or 2 below
And what I didn't appreciate as a big negative to this approach is how a union type is different from a type alias. A type alias of string admits of the string functions when declared--it really is a string and does "string things. A single case discriminated union of string--is not a string any more. To have it do "string things" you have to unwrap it. (Or write versions of those functions into your type (which might be wrappers of the string functions).) Likewise a type alias of my function accepts those parameters. A DU of my function is just a wrapper and doesn't take arguments. So this doesn't work with discriminated union:
let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
//"stoppingCondition1 is not a function and cannot be applied"
And there's not enough value in my case here to work around the wrapper. But a type alias works:
type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0 // b = true
I may not have everything straight in what I just said, but I think I'm a lot closer.
Edit 2:
Side note. My question is about defining the type of a function. And it compares using a type alias and a union type. As I worked at trying to do these, I also learned this about using a type alias:
This works (from: https://fsharpforfunandprofit.com/posts/defining-functions/ ):
type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
//or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y
but these are wrong:
let (f2 : Adder) x y = x + y // bad
let (f3 x y) : (decimal -> decimal -> decimal) = x + y // bad
let (f3 : (decimal -> decimal -> decimal)) x y = x + y // bad
And some discussion on this whole issue: F# Type declaration possible ala Haskell?
(And also, yeah, "assigning a type" isn't the right thing to say either.)
You don't "make it be of type" StoppingCondition. You declare a value of type StoppingCondition and pass Condition1 as the parameter of the DU case constructor:
let stop = StoppingCondition Condition1
That means, however, that every time you want to access the function contained in your single DU case, you have to pattern match over it in some way; that can become annoying.
You say you don't want just any functions that fulfill the signature to be valid as stopping conditions; however, it seems to be specific enough to avoid "accidentally" passing in an "inappropriate" function - with that, you could do something simpler - define StoppingCondition as a type alias for your specific function type:
type StoppingCondition = ReturnType -> ReturnType -> int -> float -> bool
Now you can use StoppingCondition everywhere you need to specify the type, and the actual values you pass/return can be any functions that fulfill the signature ReturnType -> ReturnType -> int -> float -> bool.
As has been said, you have to construct an instance of a StoppingCondition from an appropriate function, for example:
let Condition1 = StoppingCondition (fun _ _ _ _ -> true)`
One nice way to do this without weird indentation or extra parentheses is a backward pipe:
let Condition1 = StoppingCondition <| fun lastRet nextRet i fl ->
// Add function code here
The signature might be long enough to justify a record type instead of four curried parameters. It's a question of style and how it'll be used; the result may look like this:
type MyInput =
{ LastReturn : ReturnType
NextReturn : ReturnType
MyInt : int
MyFloat : float }
type StopCondition = StopCondition of (MyInput -> bool)
let impossibleCondition = StopCondition (fun _ -> false)
let moreComplicatedCondition = StopCondition <| fun inp ->
inp.MyInt < int (round inp.MyFloat)
To call the function inside a StopCondition, unwrap it with a pattern:
let testStopCondition (StopCondition c) input = c input
Specify the return type of a function is done like this:
let Condition1 lastRet nextRet i fl :StoppingCondition=
true
of course, this won't compile as true is not of the correct type.
I suspect the actual definition you want is closer to
let Condition1 :StoppingCondition=
true
though, as the type looks like it contains the function arguments.
Expanding on this, you can define such a function like:
let Condition1=fun a b c d -> StoppingCondition(fun a b c d -> whatever)
but this whole thing is pretty ugly.
Realistically, I think it is better to put all the functions in an array, which will force the types to match
So, it seems to me that you things you might want to with StoppingConditions are to create some predefined type of stopping condition.
Here are some examples of some possible stopping conditions:
let stopWhenNextGreaterThanLast = StoppingCondition (fun last next _ _ -> next > last)
let stopWhenLastGreaterThanLast = StoppingCondition (fun last next _ _ -> last> next)
(I've underscored the parameters I'm not using in my stopping condition definition)
Hopefully you can see that both of these values of type StoppingCondition.
Then you might want a function to determine if the stopping condition had been met given some parameters:
let shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
This function takes a stopping condition and the various states of your recursion and returns true or false depending on whether or not it should now stop.
This should be all you need to make use of this approach in practice.
You could extend this approach by doing something like this to cover multiple potential stopping conditions:
type StoppingCondition =
| StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
| Or of StoppingCondition * StoppingCondition
And modifying the shouldStop function
let rec shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
|Or (stp1, stp2) -> (shouldStop stp1 last next i value) || (shouldStop stp2 last next i value)
Now if we have a single condition, we stop when it's met or if we multiple conditions, we can check whether either of them are met.
Then you could Or together new stopping conditions from a base condition:
let stopWhenIIsEven = StoppingCondition (fun _ _ i _ -> i % 2 = 0)
let stopWhenValueIsZero = StoppingCondition (fun _ _ _ value -> value = 0.0)
let stopWhenIEvenOrValueZero = Or (stopWhenIIsEven, stopWhenValueIsZero)