open System.Collections.Generic open System open System.Threading // Tuples let r = 1.1 + 3.0 let rx = r.ToString() let s = "abcd" let sl = s.Length let t1 = (3, 4, 5) // t1 is int * int * int let v1, v2, v3 = t1 let t2 = "hi", true printfn "%A" (fst t2) // for pairs printfn "%A" (snd t2) // for pairs let third t = let _, _, r = t r printfn "%A" (third t1) // by pattern matching let trd' (_,_,r) = r printfn "%A" (trd' t1) printfn "%A" 1.1 // Lists let empty = [] let intList = [2;4;6;7] printfn "%A" intList printfn "%A" intList.Head printfn "%A" intList.Tail let addItem xs x = x :: xs let intList' = addItem intList 42 printfn "%A" intList' printfn "%A" (["hi";"there"] @ ["how";"are";"you"]) printfn "%A" intList'.Tail.Tail.Head printfn "%A" intList'.Tail.Tail let rec listLen'' (l1: 'w list) = if l1.IsEmpty then 0 else 1 + (listLen'' l1.Tail) // recursive length let rec listLen (l: 'a list) = if l.IsEmpty then 0 else 1 + (listLen l.Tail) // pattern length let rec listLen' l = match l with | [] -> 0 | x :: xs -> 1 + (listLen' xs) // pattern-only length let rec listLen''' = function | [] -> 0 | x :: xs -> 1 + (listLen''' xs) // recursive pattern matching (algorithmic) let rec takeFromList n l = match n, l with | 0, _ -> [] | _, [] -> [] | _, (x :: xs) -> x :: (takeFromList (n - 1) xs) printfn "%A" (takeFromList 2 intList') // helper function output let output x = printfn "%A" x // sequence - like list but values delivered as needed // comprehension syntax .. let ints = [7..20] output ints let ints' = [7..2..13] // every 2 output ints' let values step max = [1..step..max] output (values 2 20) let intseq = seq {7..13} output intseq output [for x in 7..13 -> x] output [for x in 7..13 -> x, x*x] // return tuples output [for x in 7..13 -> (printfn "computing %d" x) x, x*x] // return tuples // Lambdas let add x y = x + y let add' = fun x y -> x + y let checkThis item op = if op item then printfn "HIT" else printfn "MISS" checkThis 5 (fun x -> x > 3) checkThis "hi there" (fun x -> x.Length > 5) // type annotation (any literal not necessary a) let checkThis' (item: 'a) (op: 'a -> bool) : unit = if op item then printfn "HIT" else printfn "MISS" // constructing functions let add'' x = fun y -> x + y let add10'' = add'' 10 // closure is used to capture the value of x and then it is suded later printfn "%d" (add10'' 32) let add10 = add 10 printfn "%d" (add10 32) // no precomputation let isInList (list: 'a list) v = let lookupTable = new HashSet<'a>(list) printfn "lookup table created, looking up value" lookupTable.Contains v printfn "%b" (isInList ["hi"; "there"; "Oliver"] "there") printfn "%b" (isInList ["hi"; "there"; "Oliver"] "Anna") // close the common list let isInListClever = isInList ["hi"; "there"; "Oliver"] printfn "%b" (isInListClever "there") printfn "%b" (isInListClever "Anna") // construct a function let constructLookup (list: 'a list) = let lookupTable = new HashSet<'a>(list) printfn "lookup table created" fun v -> printfn "looking up value" lookupTable.Contains v let isInListClever' = constructLookup ["hi"; "there"; "Oliver"] printfn "%b" (isInListClever' "there") printfn "%b" (isInListClever' "Anna") // RECURSION let rec fact x = if x = 1 then 1 else x * (fact (x - 1)) printfn "%d" (fact 5) // will not work //let fnB() = fnA() //let fnA() = fnB() // 2 definitions ad one syntactic unit (context) // resulsive functions that call each other must be combined with possibly masny ANDs let rec fnB() = fnA() and fnA() = fnB() // F# resolves stack overflow (biggest problem with recursion) so we are ok to do: let showVals() = let r = Random() let rec dl() = printfn "%d" (r.Next()) Thread.Sleep(1000) dl() dl() showVals() // ENUMS type MyEnum = | First = 0 | Second = 1 // Discriminating Union Type (union of types) type Product = | OwnProduct of string | SupplierReference of int type Count = int // type alias type StockBooking = | Incoming of Product * Count // tuple | Outgoing of Product * Count // tuple let p1 = Product.OwnProduct("bread") let p2 = SupplierReference(53) let bookings = [ Incoming(OwnProduct("Rubber Chicken"), 50); Incoming(SupplierReference(112), 18); Outgoing(OwnProduct("Pulley"),6); Outgoing(SupplierReference(37),64); ] // record type type Rectangle = { Width: int; Height: int; } let rect1 = { Width = 10; Height = 20; } let rect2 : Rectangle = { Width = 10; Height = 20; } type Circle = { Radius: float } member x.RadiusSquare with get() = x.Radius * x.Radius member x.CalcArea() = System.Math.PI * x.RadiusSquare let c1 = {Radius = 3.3} // MUTABLE type Circle' = { mutable Radius: float } member x.RadiusSquare with get() = x.Radius * x.Radius member x.CalcArea() = System.Math.PI * x.RadiusSquare let c1' = {Radius = 3.3} c1'.Radius <- 5.4 // mutate property // functional filter let rec filter f l = match l with | [] -> [] | x :: xs -> (if f x then [x] else []) @ (filter f xs) printfn "%A" (filter (fun x -> x < 10) [1;3;10;20]) let rec maplist f l = match l with | [] -> [] | x :: xs -> f x :: (maplist f xs) printfn "%A" (maplist (fun x -> x * x) [1;3;10;20]) let rec reduce f s l = match l with | [] -> s | x :: xs -> reduce f (f s x) xs printfn "%A" (reduce (fun r v -> r + v) 0 [1;3;10;20]) printfn "%A" (reduce (+) 0 [1;3;10;20])