I have a text file of rain measured over 3 years, where each number after the year corresponds to the month.
For example, in
2002 1.17 0.78 7.11 5.17 5.84 4.29 1.12 4.06 1.9 2.07 1.47 1.53
2001 1.24 3.22 1.61 3.33 6.55 2.4 3.5 1.32 3.9 6.04 1.69 1.13
2000 1.277 1.4 1.17 5.74 6.48 4.81 4.07 3.19 6.2 1.95 2.65 1.7
In 2002, Average rainfall in Feb was 0.78.
I made a list of tuples, in the format (year,values,average,min,max) where years is int, values is a float list, average is an int that averages all of 'values', min is an int holding the smallest 'value' and max.
My question:
I am able to print the smallest value from all the tuples using List.minBy fourth mylist and the year it came from (because its single element), but how do I correspond that number to the month it came from?
I have
let TupleWithSmallestValue= List.minBy min biglist
let (year,_,_,min,_) = TupleWithSmallestValue
printfn"Min rainfall:\t%A; %A" min year
and I was thinking something along the lines of :
List.map (fun (year,(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec), avg, min, max) -> somehow print the min and the month it came from )
But I know that's wrong and I'm trying to address each value to make it correspond to a month, just like I did with my example above. If my question is clear enough, how do I do this? I am a C++ programmer but I like the style of this language. Just missing some basics.
Something like this should work:
let months = [ "Jan"; "Feb"; ...; "Dec" ]
let (year, values, _, min, _) = TupleWithSmallestValue
let month = values |> List.mapi (fun i x -> (i, x))
|> List.find (fun (m, v) -> v = min)
|> fst
|> List.nth months
Related
I've just been doing some validation on value to see it is a product of three. Great use the modulus function. I want to pipe to it. Great use a partial application. But apparently not.
This is an example from my fsi in vs code.
> 27 % 3
-
- ;;
val it : int = 0
> (%) 3 27
- ;;
val it : int = 3
I really didn't expect to get a different result from an infix vs a partial.
Here is the operation in a pipe for context:
...
|> Seq.length // 27
|> (%) 3 // 3
Because you have the operands flipped. (%) 3 27 actually means 3 % 27, not 27 % 3, i.e. you want (%) 27 3.
Partial application of an infix doesn't work as I expected. The statement in my qustion is incorrect and this isn't a bug. It might be a fairly common missunderstanding for beginers so its worth a good explaination.
(%) x y = x % y
Therefore
(%) 27 3
= 27 % 3
= 0
The confusion comes when piping in the final value, the y.
you should not expect
y
|> (%) x
to result in
y % x
but rather
x % y
This is a little bit confusing particularly if you have used an infix operator, which does treats inputs symetrically (e.g +,=,<>,*), without questioning too deeply. You must take care that order of values supplied to an infix opperator are correct, even if it looks right at first inspection.
The clearest and most verbose way to handle an infix opperator, which accepts values in the opposite order to which you wish to supply them, is to just write out a lambda. However, there is also the option to back pipe '<|'.
Here is a snippet of code which was causing me a bug due to my misuse of the partially applied infix.
...
|> Seq.length // 27
|> (%) 3 // 3 % 27 = 3
It could be written with a backpipe to perform as expected
...
|> Seq.length // 27
|> (%) <|3 // 27 % 3 = 0
or more clearly with a lambda
...
|> Seq.length // 27
|> (fun x -> x % 3 // 27 % 3 = 0
I have a text file of rain measured over 3 years, where each number after the year corresponds to the month.
For example, in
2002 1.17 0.78 7.11 5.17 5.84 4.29 1.12 4.06 1.9 2.07 1.47 1.53
2001 1.24 3.22 1.61 3.33 6.55 2.4 3.5 1.32 3.9 6.04 1.69 1.13
2000 1.277 1.4 1.17 5.74 6.48 4.81 4.07 3.19 6.2 1.95 2.65 1.7
In 2002, Average rainfall in Feb was 0.78.
I made a list of tuples called mylist, in the format (year,values,average,min,max) where years is int, values is a float list, average is an int that averages all of 'values', min is an int holding the smallest 'value' and max.
My question:
How do I calculate the average of the n'th elements in the list, like the average of month January, Feb, March....
I have:
let months = [ "Jan"; "Feb"; "Mar"; "Apr"; "May"; "Jun"; "Jul"; "Aug"; "Sep"; "Oct"; "Nov"; "Dec" ] //string list
and I'm thinking of something along the lines of:
mylist |> List.map (fun (_,values, _, _, _) -> average 0th index across all tuples, print Jan, then average 1st index across all tuples, print Feb, etc...)
or
mylist |> List.map (fun (_,values, _, _, _) -> printfn"%A %A" List.average 0thIndex,0thMonth....List.average 1stIndex, 1stMonth, etc...)
But I'm not familiar enough with the functional language to know all operations on lists and maps. Am more comfortable with Java and C
I would map values to list of lists:
let vs = mylist |> List.map (fun (_, values, _, _, _) -> values)
Then transpose it to get list of lists of values in months.
let mvs = vs |> transpose
And then calculate averages using:
let avgs = mvs |> List.map List.average
Use transpose from this answer.
Oh, and if you want to print them in a nice way:
avgs |> List.iteri (fun i avg -> printfn "Month %s average: %d" months.[i] avg)
I have a record that holds one DateTime array and 2 double arrays all of the same length and related by index.
I want to get the average of the delta between the 2 double arrays based the hour of the DateTime. So I'll have 24 averages in the end. All data in index 0 of the arrays are related / happen at the same time, and so on for all the indexes. Perhaps I should instead have 1 array of tuples or records that each holds just one datetime, and 2 doubles.
But anyway this is what I have so far:
let data2 = [ for i in 0..data.Date.Length-1 do
yield data.Date.[i].Hour, data.High.[i] - data.Low.[i]]
And here is where my inexperience hurts the most. The only thing I can think of is to do some kind of matching or if statements that go through all of those 24 hours (0 - 23) and having individual mutable values for each hour. There must be an easier way. I've been unsuccessful so far in finding a way.
I think you want to do
let grouped = data2 |> Seq.GroupBy (fst) |> Seq.map (fun (a,b) -> Seq.average (b |> Seq.map (snd)))
Here Seq.groupBy will group all the elements which have an identical first element. You can then take the average with Seq.average.
Note:
I think your original expression for data2 would be better written as
data.Date |> Array.mapi (fun i t -> t.Hour,data.High.[i]-data.Low.[i])
These are 2 functions, fun1 takes 1 parameter, fun2 takes 4 extra useless parameters. When I targeted for x64, fun1 takes 4s but fun2 takes less than 1s. If I targeted for anycpu, then both take less than 1s.
There is a similar question I asked here
why Seq.iter is 2x faster than for loop if target is for x64?
It is compiled in .Net 4.5 Visual Studio 2012, F# 3.0, run in windows 7 x64
open System
open System.Diagnostics
type Position =
{
a: int
b: int
}
[<EntryPoint>]
let main argv =
let fun1 (pos: Position[]) = //<<<<<<<< here
let functionB x y z = 4
Array.fold2 (fun acc x y -> acc + int64 (functionB x x y)) 0L pos pos
let fun2 (pos: Position[]) u v w x = //<<<<<<<< here
let functionB x y z = 4
Array.fold2 (fun acc x y -> acc + int64 (functionB x x y)) 0L pos pos
let s = {a=2;b=3}
let pool = [|s;s;s|]
let test1 n =
let mutable x = 0L
for i in 1 .. n do
x <- fun1 pool
let test2 n =
let mutable x = 0L
for i in 1 .. n do
x <- fun2 pool 1 2 3 4
let sw = new Stopwatch()
sw.Start()
test2 10000000
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Restart()
test1 10000000
sw.Stop()
Console.WriteLine(sw.Elapsed)
0 // return an integer exit code
This isn't a complete answer, it is first diagnostics of the problem.
I can reproduce the behaviour with the same configuration. If you turn on F# Interactive 64-bit in Tools -> Options -> F# Tools -> F# Interactive, you can observe the same behaviour there.
Diferrent from the other question, x64 jitter isn't a problem. It turns out "Generate tail calls" option in Project property causes considerable slowdown of test1 compared to test2. If you turn off that option, two cases are at similar speeds.
On the other hand, you can use inline keyword on fun1 so that tail call isn't needed. Two examples are comparable in execution time again no matter fun2 is inlined or not.
That said, it is weird that adding tail. opcode to fun1 makes it much slower than (doing the same with) fun2. You may contact F# team for further investigation.
The difference is almost certainly a quirk of the JITer. It also explains the inconsistent results. This is a common problem with micro-benchmarking tests like this. Perform one or more redundant executions of the methods in order to compile the whole thing behind the scenes, and time the last one. They will be identical.
You can get more bizarre results than this due to this quirk.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Looks like here in StackOveflow there is a group of F# enthusiasts.
I'd like to know better this language, so, apart from the functional programming theory, can you point me to the better starting points to start using the F# language? I mean, tutorials, how-tos, but first of all working samples to have the chance to start doing something and enjoy the language.
Thanks a lot
Andrea
Not to whore myself horribly but I wrote a couple F# overview posts on my blog here and here. Chris Smith (guy on the F# team at MS) has an article called 'F# in 20 minutes' - part 1 and part 2.
Note you have to be careful as the latest CTP of F# (version 1.9.6.0) has some seriously breaking changes compared to previous versions, so some examples/tutorials out there might not work without modification.
Here's a quick run-down of some cool stuff, maybe I can give you a few hints here myself which are clearly very brief and probably not great but hopefully gives you something to play with!:-
First note - most examples on the internet will assume 'lightweight syntax' is turned on. To achieve this use the following line of code:-
#light
This prevents you from having to insert certain keywords that are present for OCaml compatibility and also having to terminate each line with semicolons. Note that using this syntax means indentation defines scope. This will become clear in later examples, all of which rely on lightweight syntax being switched on.
If you're using the interactive mode you have to terminate all statements with double semi-colons, for example:-
> #light;;
> let f x y = x + y;;
val f : int -> int -> int
> f 1 2;;
val it : int = 3
Note that interactive mode returns a 'val' result after each line. This gives important information about the definitions we are making, for example 'val f : int -> int -> int' indicates that a function which takes two ints returns an int.
Note that only in interactive do we need to terminate lines with semi-colons, when actually defining F# code we are free of that :-)
You define functions using the 'let' keyword. This is probably the most important keyword in all of F# and you'll be using it a lot. For example:-
let sumStuff x y = x + y
let sumStuffTuple (x, y) = x + y
We can call these functions thus:-
sumStuff 1 2
3
sumStuffTuple (1, 2)
3
Note there are two different ways of defining functions here - you can either separate parameters by whitespace or specify parameters in 'tuples' (i.e. values in parentheses separated by commas). The difference is that we can use 'partial function application' to obtain functions which take less than the required parameters using the first approach, and not with the second. E.g.:-
let sumStuff1 = sumStuff 1
sumStuff 2
3
Note we are obtaining a function from the expression 'sumStuff 1'. When we can pass around functions just as easily as data that is referred to as the language having 'first class functions', this is a fundamental part of any functional language such as F#.
Pattern matching is pretty darn cool, it's basically like a switch statement on steroids (yeah I nicked that phrase from another F#-ist :-). You can do stuff like:-
let someThing x =
match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| x when x < 0 -> "negative = " + x.ToString()
| _ when x%2 = 0 -> "greater than two but even"
| _ -> "greater than two but odd"
Note we use the '_' symbol when we want to match on something but the expression we are returning does not depend on the input.
We can abbreviate pattern matching using if, elif, and else statements as required:-
let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd"
F# lists (which are implemented as linked lists underneath) can be manipulated thus:-
let l1 = [1;2;3]
l1.[0]
1
let l2 = [1 .. 10]
List.length l2
10
let squares = [for i in 1..10 -> i * i]
squares
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let square x = x * x;;
let squares2 = List.map square [1..10]
squares2
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let evenSquares = List.filter (fun x -> x % 2 = 0) squares
evenSqares
[4; 16; 36; 64; 100]
Note the List.map function 'maps' the square function on to the list from 1 to 10, i.e. applies the function to each element. List.filter 'filters' a list by only returning values in the list that pass the predicate function provided. Also note the 'fun x -> f' syntax - this is the F# lambda.
Note that throughout we have not defined any types - the F# compiler/interpreter 'infers' types, i.e. works out what you want from usage. For example:-
let f x = "hi " + x
Here the compiler/interpreter will determine x is a string since you're performing an operation which requires x to be a string. It also determines the return type will be string as well.
When there is ambiguity the compiler makes assumptions, for example:-
let f x y = x + y
Here x and y could be a number of types, but the compiler defaults to int. If you want to define types you can using type annotation:-
let f (x:string) y = x + y
Also note that we have had to enclose x:string in parentheses, we often have to do this to separate parts of a function definition.
Two really useful and heavily used operators in F# are the pipe forward and function composition operators |> and >> respectively.
We define |> thus:-
let (|>) x f = f x
Note that you can define operators in F#, this is pretty cool :-).
This allows you to write things in a clearer way, e.g.:-
[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
Will allow you to obtain the first 10 even squares. That is clearer than:-
List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10])
Well, at least I think so :-)
Function composition defined by the >> operator is defined as follows:-
let (>>) f g x = g(f(x))
I.e. you forward-pipe an operation only the parameter of the first function remains unspecified. This is useful as you can do the following:-
let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0)
Here mapFilter will accept a list an input and return the list filtered as before. It's an abbreviated version of:-
let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
If we want to write recursive functions we have to define the function as recursive by placing 'rec' after the let. Examples below.
Some cool stuff:-
Factorial
let rec fact x = if x <= 1 then 1 else x * fact (x-1)
nth Fibonacci Number
let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2)
FizzBuzz
let (/%) x y = x % y = 0
let fb = function
| x when x /% 15 -> "FizzBuzz"
| x when x /% 3 -> "Fizz"
| x when x /% 5 -> "Buzz"
| x -> x.ToString()
[1..100] |> List.map (fb >> printfn "%s")
Anyway that's a very brief overview, hopefully it helps a little!!
Without doubt, you should purchase Don Syme's excellent book "Expert F#". The book is very well written and is suitable for both beginners and experts alike. In it, you'll find both introductory material and much more challenging material too. At nearly 600 pages it is good value for money.
I found that it taught me a lot of useful techniques for writing more functional C# as well as providing all the reference material I needed to get started writing Windows hosted F# applications.
The book is published by Apress and has an accompanying web site at:
http://www.expert-fsharp.com/default.aspx
#kronoz - well thanks a lot for your long answer, that's a really good place to start from. I'll follow your advices, and look for the book #vecstasy mentioned.
now, let me go coding :-)
let thanksalot = "thanks a lot"
printfn "%s" (thanksalot);;
I've been reading Real World Functional Programming
With examples in F# and C# by:Tomas Petricek
So far I find it very good at teaching F# concepts by showing the implementations in C# on the side. Great for OO Programmers.
The first chapter of my book F# for Scientists is freely available here. We have a series of free F# toy programs here. The first article from our F#.NET Journal is freely available here.
Check out the F# Developer Center. There is also hubFS, a forum dedicated to F#.
If you have the current CTP release in Visual Studio it lets you create a F# Tutorial project, which gives you a Tutorial.fs, exactly containing what it's name suggests.
That tutorial also points to a larger collection of F# examples at Microsoft.
Also, there is an F# samples project going on at CodePlex.
Hope this helps,
Michiel