1 people like it.

Seattle F# Meetup 7/17/2013 Example Code - Functional

Functional-style examples used during my talk for the Seattle F# Meetup on 7/17/2013 See corresponding imperative-style examples at http://fssnip.net/iO

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
160: 
161: 
162: 
163: 
164: 
165: 
166: 
167: 
168: 
169: 
170: 
171: 
172: 
173: 
174: 
175: 
176: 
177: 
178: 
179: 
180: 
181: 
182: 
183: 
184: 
185: 
186: 
187: 
namespace Talk.Functional

open System
open System.Threading
open System.Diagnostics
open System.Collections.Generic

(* PATTERN MATCHING *)

module Example1_functional =
    let message =
        match Console.ReadKey().KeyChar with
        |'Q' -> "Quit!"
        |'?' -> "Help!"
        |key -> sprintf "You hit %c" key

    printfn "%s" message


module Example2_functional =
    let processArray arr =
        match arr with
        | [| 42 |] -> "1 element, 42"
        | [| x; y; _ |] when x < y -> sprintf "%d < %d" x y
        | [| _; _; z |] ->  sprintf "3 elements, last is %d" z
        | _ ->  sprintf "%A" arr


(* ACTIVE PATTERNS *)

module Example3_functional = 

    let (|Negative|Zero|Positive|) n =
        if n < 0 then Negative
        elif n = 0 then Zero
        else Positive

    let (|Prime|Composite|Neither|) n =
        match n with
        | Zero
        | 1
        | Negative ->
            Neither
        | Positive ->
            let mutable factors = []
            let mutable remaining = n
            let mutable divisor = 2

            while remaining > 1 do
                if remaining % divisor = 0 then
                    factors <- divisor :: factors
                    remaining <- remaining / divisor
                else
                    divisor <- divisor + 1

            match factors with
            | [_] -> Prime
            | _ -> Composite(factors)

    let describeNumber n =
        match n with
        | Prime -> printfn "n is prime"
        | Composite(factors) -> printfn "n in composite, with factors %A" factors
        | Neither -> printfn "n is neither prime nor composite"

(* RECURSIVE LOOPS *)

module Example4_functional =
 
    let rec forLoop i =
        match i <= 5 with
        | false -> ()
        | true ->
            printfn "%d" i
            forLoop (i + 1)
    forLoop 1

    let rec whileLoop start =
        match (DateTime.Now - start) < TimeSpan.FromSeconds(2.) with
        | false -> ()
        | true ->
            printfn "Looping..."
            Thread.Sleep(300)
            whileLoop start
    whileLoop DateTime.Now


module Example5_functional =

    let rec whileLoop start (rnd:Random) =
        if not ((DateTime.Now - start) < TimeSpan.FromSeconds(2.)) then
            printfn "Looping..."
            Thread.Sleep(300)
            if rnd.Next() % 10 <> 0 then
                whileLoop start rnd
    whileLoop DateTime.Now (Random())
    

module Example6_functional =

    let factorPositive n = 
        let rec loop remaining divisor factors =
            match (remaining > 1, remaining % divisor) with
            | (false, _) -> factors
            | (_, 0) -> loop divisor (remaining/divisor) (divisor::factors)
            | _ -> loop (divisor + 1) remaining factors
            
        loop n 2 []


module Example3_functional_full = 
    let factorPositive n = 
        let rec loop remaining divisor factors =
            match (remaining > 1, remaining % divisor) with
            | (false, _) -> factors
            | (_, 0) -> loop divisor (remaining/divisor) (divisor::factors)
            | _ -> loop (divisor + 1) remaining factors
            
        loop 2 n []

    let (|Negative|Zero|Positive|) n =
        if n < 0 then Negative
        elif n = 0 then Zero
        else Positive

    let (|Prime|Composite|Neither|) n =
        match n with
        | Zero | 1 | Negative -> Neither
        | Positive ->            
            match factorPositive n with
            | [_] -> Prime
            | factors -> Composite(factors)

    let describeNumber n =
        match n with
        | Prime -> printfn "n is prime"
        | Composite(factors) -> printfn "n in composite, with factors %A" factors
        | Neither -> printfn "n is neither prime nor composite"
        
(* HIGHER-ORDER FUNCTIONS FOR COLLECTION PROCESSING *)

module Example7_functional =
    let myArray = [|"one"; "two"; "three"|]
    let stringLengths =
        myArray |> Array.map (fun elem -> elem.Length)

        
module Example8_functional =
    let myArray = [|"one"; "two"; "three"|]
    let sumOfStringLengths =
        myArray |> Array.fold (fun accum elem -> accum + elem.Length) 0


module Example9_functional = 

    let myArray = [|"one"; "two"; "three"|]
    let filtered =
        myArray |> Array.filter (fun item -> item.Length = 3)

module Example10_functional =

    let myArray = [|"one"; "two"; "three"|]
    myArray
    |> Array.map (fun elem -> (elem, elem.Length))
    |> Array.filter (fun (_, length) -> length = 3)
    |> Array.iter (fun (str, length) ->
            printfn "Length of %A is %d" str length
    )


module OtherFunStuff = 

    let time f = 
        let sw = Stopwatch.StartNew()
        f() |> ignore
        sw.Stop()
        printfn "Elapsed: %A" sw.Elapsed

    let memoize f =
        let cache = Dictionary<_, _>()
        fun x ->
            match cache.TryGetValue(x) with
            | (true, value) -> value
            | _ ->
                let value = f x
                cache.Add(x, value)
                value
namespace System
namespace System.Threading
namespace System.Diagnostics
namespace System.Collections
namespace System.Collections.Generic
val message : string

Full name: Talk.Functional.Example1_functional.message
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
Console.ReadKey() : ConsoleKeyInfo
Console.ReadKey(intercept: bool) : ConsoleKeyInfo
val key : char
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val processArray : arr:int [] -> string

Full name: Talk.Functional.Example2_functional.processArray
val arr : int []
val x : int
val y : int
val z : int
val n : int
active recognizer Zero: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional.( |Negative|Zero|Positive| )
active recognizer Negative: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional.( |Negative|Zero|Positive| )
active recognizer Positive: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional.( |Negative|Zero|Positive| )
val mutable factors : int list
val mutable remaining : int
val mutable divisor : int
val describeNumber : n:int -> unit

Full name: Talk.Functional.Example3_functional.describeNumber
active recognizer Prime: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional.( |Prime|Composite|Neither| )
active recognizer Composite: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional.( |Prime|Composite|Neither| )
val factors : int list
active recognizer Neither: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional.( |Prime|Composite|Neither| )
val forLoop : i:int -> unit

Full name: Talk.Functional.Example4_functional.forLoop
val i : int
val whileLoop : start:DateTime -> unit

Full name: Talk.Functional.Example4_functional.whileLoop
val start : DateTime
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
property DateTime.Now: DateTime
Multiple items
type TimeSpan =
  struct
    new : ticks:int64 -> TimeSpan + 3 overloads
    member Add : ts:TimeSpan -> TimeSpan
    member CompareTo : value:obj -> int + 1 overload
    member Days : int
    member Duration : unit -> TimeSpan
    member Equals : value:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member Hours : int
    member Milliseconds : int
    member Minutes : int
    ...
  end

Full name: System.TimeSpan

--------------------
TimeSpan()
TimeSpan(ticks: int64) : unit
TimeSpan(hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : unit
TimeSpan.FromSeconds(value: float) : TimeSpan
Multiple items
type Thread =
  inherit CriticalFinalizerObject
  new : start:ThreadStart -> Thread + 3 overloads
  member Abort : unit -> unit + 1 overload
  member ApartmentState : ApartmentState with get, set
  member CurrentCulture : CultureInfo with get, set
  member CurrentUICulture : CultureInfo with get, set
  member DisableComObjectEagerCleanup : unit -> unit
  member ExecutionContext : ExecutionContext
  member GetApartmentState : unit -> ApartmentState
  member GetCompressedStack : unit -> CompressedStack
  member GetHashCode : unit -> int
  ...

Full name: System.Threading.Thread

--------------------
Thread(start: ThreadStart) : unit
Thread(start: ParameterizedThreadStart) : unit
Thread(start: ThreadStart, maxStackSize: int) : unit
Thread(start: ParameterizedThreadStart, maxStackSize: int) : unit
Thread.Sleep(timeout: TimeSpan) : unit
Thread.Sleep(millisecondsTimeout: int) : unit
val whileLoop : start:DateTime -> rnd:Random -> unit

Full name: Talk.Functional.Example5_functional.whileLoop
val rnd : Random
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
Random() : unit
Random(Seed: int) : unit
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
val factorPositive : n:int -> int list

Full name: Talk.Functional.Example6_functional.factorPositive
val loop : (int -> int -> int list -> int list)
val remaining : int
val divisor : int
val factorPositive : n:int -> int list

Full name: Talk.Functional.Example3_functional_full.factorPositive
active recognizer Zero: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional_full.( |Negative|Zero|Positive| )
active recognizer Negative: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional_full.( |Negative|Zero|Positive| )
active recognizer Positive: int -> Choice<unit,unit,unit>

Full name: Talk.Functional.Example3_functional_full.( |Negative|Zero|Positive| )
val describeNumber : n:int -> unit

Full name: Talk.Functional.Example3_functional_full.describeNumber
active recognizer Prime: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional_full.( |Prime|Composite|Neither| )
active recognizer Composite: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional_full.( |Prime|Composite|Neither| )
active recognizer Neither: int -> Choice<unit,int list,unit>

Full name: Talk.Functional.Example3_functional_full.( |Prime|Composite|Neither| )
val myArray : string []

Full name: Talk.Functional.Example7_functional.myArray
val stringLengths : int []

Full name: Talk.Functional.Example7_functional.stringLengths
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val elem : string
property String.Length: int
val myArray : string []

Full name: Talk.Functional.Example8_functional.myArray
val sumOfStringLengths : int

Full name: Talk.Functional.Example8_functional.sumOfStringLengths
val fold : folder:('State -> 'T -> 'State) -> state:'State -> array:'T [] -> 'State

Full name: Microsoft.FSharp.Collections.Array.fold
val accum : int
val myArray : string []

Full name: Talk.Functional.Example9_functional.myArray
val filtered : string []

Full name: Talk.Functional.Example9_functional.filtered
val filter : predicate:('T -> bool) -> array:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.filter
val item : string
val myArray : string []

Full name: Talk.Functional.Example10_functional.myArray
val length : int
val iter : action:('T -> unit) -> array:'T [] -> unit

Full name: Microsoft.FSharp.Collections.Array.iter
val str : string
module OtherFunStuff

from Talk.Functional
val time : f:(unit -> 'a) -> unit

Full name: Talk.Functional.OtherFunStuff.time
val f : (unit -> 'a)
val sw : Stopwatch
Multiple items
type Stopwatch =
  new : unit -> Stopwatch
  member Elapsed : TimeSpan
  member ElapsedMilliseconds : int64
  member ElapsedTicks : int64
  member IsRunning : bool
  member Reset : unit -> unit
  member Restart : unit -> unit
  member Start : unit -> unit
  member Stop : unit -> unit
  static val Frequency : int64
  ...

Full name: System.Diagnostics.Stopwatch

--------------------
Stopwatch() : unit
Stopwatch.StartNew() : Stopwatch
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
Stopwatch.Stop() : unit
property Stopwatch.Elapsed: TimeSpan
val memoize : f:('a -> 'b) -> ('a -> 'b) (requires equality)

Full name: Talk.Functional.OtherFunStuff.memoize
val f : ('a -> 'b) (requires equality)
val cache : Dictionary<'a,'b> (requires equality)
Multiple items
type Dictionary<'TKey,'TValue> =
  new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
  member Add : key:'TKey * value:'TValue -> unit
  member Clear : unit -> unit
  member Comparer : IEqualityComparer<'TKey>
  member ContainsKey : key:'TKey -> bool
  member ContainsValue : value:'TValue -> bool
  member Count : int
  member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  member Item : 'TKey -> 'TValue with get, set
  ...
  nested type Enumerator
  nested type KeyCollection
  nested type ValueCollection

Full name: System.Collections.Generic.Dictionary<_,_>

--------------------
Dictionary() : unit
Dictionary(capacity: int) : unit
Dictionary(comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>) : unit
Dictionary(capacity: int, comparer: IEqualityComparer<'TKey>) : unit
Dictionary(dictionary: IDictionary<'TKey,'TValue>, comparer: IEqualityComparer<'TKey>) : unit
val x : 'a (requires equality)
Dictionary.TryGetValue(key: 'a, value: byref<'b>) : bool
val value : 'b
Dictionary.Add(key: 'a, value: 'b) : unit
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/iP
Posted:11 years ago
Author:Lincoln Atkinson
Tags: talk , functional , meetup , examples