F# Rocks
-
Upload
lorenzo-stoakes -
Category
Technology
-
view
630 -
download
0
Transcript of F# Rocks
F♯
It Rocks. But Why?
Why Does it Rock?
• It makes it easy to write code which communicates its purpose clearly.
• Static guarantees without the screen fuzz.
• Fewer surprises == fewer bugs.
• Just ‘cos.
Big Picture
• Succinct“Succinctness is Power” - Paul Graham, 2002
• Declarative
• Leverages .net framework libraries
• Interoperates with .net libraries/applications
IncomprehensibleBunch o’ Code
printfn "Hello, world!"
let rec fib =function| 0 | 1 as n -‐> n| n -‐> fib (n -‐ 1) + fib (n -‐ 2)
The Obvious Stuff
Project Euler Prob. 1
[ for i in 1..999 do if i % 3 = 0 || i % 5 = 0 then yield i ]|> List.sum|> printfn "%i"
Find the sum of all the multiples of 3 or 5 below 1000.
let sq n = n * nlet sumUpTo n = n * (n + 1) / 2let sumSqUpTo n = [1..n] |> List.fold (fun s x -‐> s + sq x) 0
let sqSumUpTo = sumUpTo >> sq
sqSumUpTo 100 -‐ sumSqUpTo 100|> abs|> printfn "%i"
Project Euler Prob. 6Find the difference between the sum of the squares of the first one
hundred natural numbers and the square of the sum.
Juicier Example -Simple Parser
Core Types
type Expr<'a> =| Value of 'a| Add of Expr<'a> * Expr<'a>| Subtract of Expr<'a> * Expr<'a>
type Token =| Value of string| Add | Subtract
Lexer I
let (|Empty|_|) (s: seq<_>) = if Seq.isEmpty s then Some () else None
let (|Regex|_|) regex str = Regex.Matches(str, regex) |> Seq.cast<Match> |> function | Empty -‐> None | ms -‐> ms |> Seq.map (fun m -‐> m.Value) |> List.ofSeq |> Some
Lexer II
let lex (str: string) = let assign = function | "+" -‐> Token.Add | "-‐" -‐> Token.Subtract | v -‐> Token.Value v
let pattern = "[\+\-‐]|([^\+\-‐\s]+)"
str |> function | Regex pattern ms -‐> ms |> List.map assign | _ -‐> []
Parserlet parse (conv: string -‐> 'a) (tokens: Token List) = let get = conv >> Expr.Value
let (|Val|) = function | Token.Value str -‐> str |> get | _ -‐> failwith "Parse Error."
let add l r = Expr.Add (l, r) let sub l r = Expr.Subtract (l, r)
let rec expr = function | (Val v) :: Token.Add :: tl -‐> add (expr tl) v | (Val v) :: Token.Subtract :: tl -‐> sub (expr tl) v | (Val v) :: [] -‐> v | _ -‐> failwith "Parse Error."
tokens |> List.rev |> expr
Evaluator
let rec eval (exp: Expr<_>) = let assoc = GlobalAssociations.GetNumericAssociation ()
match exp with | Expr.Value v -‐> v | Expr.Add (l, r) -‐> assoc.Add (eval l, eval r) | Expr.Subtract (l, r) -‐> assoc.Subtract (eval l, eval r)
assert ("10 + 3 -‐ 5 -‐ 6 + 2" |> lex |> parse Int32.Parse |> eval = 4)
assert ("10.5 + 3.7 -‐ 5.2 -‐ 6.7 + 2.5" |> lex |> parse Double.Parse |> eval = 4.8)
Tests
End OfIncomprehensibleBunch o’ Code
So What?
• The tour should give an indication of the ingredients of F#’s awesomeness
• You often end up write the code right first time
• Flexible so you can go mutable/interoperate with .net as needed
Mea Culpa
• 5 minutes isn’t long enough to do it justice
• I’ve missed out many, many, many brill things
• I’m just ‘some guy’ who likes F♯ - so
excuse my mistakes/obvious lack of skillz
• Go and play with it! It rocks! Honest!