25
Functional Linear Data Structures Form a Semantically Coherent Set Jack Fox jackfoxy.com craftyThoughts @foxyjackfox Bibliography jackfoxy.com/Lambda_Jam_fsharp_bibliography Sample Code github.com/jackfoxy/ FunctionalLinearDataStructures

Semantically coherent functional linear data structures

Embed Size (px)

DESCRIPTION

Condensed version of my Lambda Jam talk presented to the N.Y. City F# User Group

Citation preview

Page 1: Semantically coherent functional linear data structures

Functional Linear Data Structures Form a Semantically Coherent Set

Jack Foxjackfoxy.com craftyThoughts

@foxyjackfox

Bibliographyjackfoxy.com/Lambda_Jam_fsharp_bibliography

Sample Codegithub.com/jackfoxy/FunctionalLinearDataStructures

Page 2: Semantically coherent functional linear data structures

• Orderby construction / sorted / random

• Evaluationeager / lazy

• Peekfirst / last / indexed

• Constructionfirst / last / insert

• Remove (Deconstruct)first / last / indexed

choose 1

choose 1

choose 1 – 2, or #3

choose 0 – 2, or #3

choose 0 – 2, or #3

(insert only for sorted & random)

Page 3: Semantically coherent functional linear data structures

Seq lets you transform structures

let thisIsTrue = seq {1..10} |> Array.ofSeq |> Deque.ofSeq |> DList.ofSeq |> FlatList.ofSeq |> Heap.ofSeq false |> LazyList.ofSeq |> Queue.ofSeq |> RandomAccessList.ofSeq |> Vector.ofSeq |> List.ofSeq = [1..10]

Page 4: Semantically coherent functional linear data structures

…and apply any of 68 Seq Module functions

seq {1.0..10.0} |> Heap.ofSeq false |> Seq.average

seq {1..10} |> Deque.ofSeq |> Seq.fold (fun state t -> (2 * t)::state) []

seq {1..10} |> RandomAccessList.ofSeq |> Seq.mapi (fun i t -> i * t)

seq {1..10} |> Vector.ofSeq |> Seq.reduce (fun acc t -> acc * t )

Page 5: Semantically coherent functional linear data structures

Unfold Infinite Sequences

unfold starts here

Page 6: Semantically coherent functional linear data structures

Markov chaintype Weather = Sunny | Cloudy | Rainy

let nextDayWeather today probability = match (today, probability) with | Sunny, p when p < 0.05 -> Rainy | Sunny, p when p < 0.40 -> Cloudy | Sunny, _ -> Sunny | Cloudy, p when p < 0.30 -> Rainy | Cloudy, p when p < 0.50 -> Sunny | Cloudy, _ -> Cloudy | Rainy, p when p < 0.15 -> Sunny | Rainy, p when p < 0.75 -> Cloudy | Rainy, _ -> Rainy

Page 7: Semantically coherent functional linear data structures

let NextState (today, (random:Random), i) = let nextDay = nextDayWeather today (random.NextDouble()) printfn "day %i is forecast %A" i nextDay Some (nextDay, (nextDay, random, (i + 1L)))

let forecastDays = Seq.unfold NextState (Sunny, (new Random()), 0L)

printfn "%A" (Seq.take 5 forecastDays |> Seq.toList)> day 0 is forecast Sunny day 1 is forecast Sunny day 2 is forecast Cloudy day 3 is forecast Rainy day 4 is forecast Cloudy [Sunny; Sunny; Cloudy; Rainy; Cloudy]

Page 8: Semantically coherent functional linear data structures

printfn "%A" (Seq.skip 5 forecastDays |> Seq.take 5 |> Seq.toList) > day 0 is forecast Sunny

… day 9 is forecast Sunny [Cloudy; Rainy; Sunny; Cloudy; Sunny]

printfn "don't try this at home! %i" (Seq.length forecastDays)

printfn "don't try this at home either! %A" (forecastDays |> List.ofSeq)

Page 9: Semantically coherent functional linear data structures

So far:Linear Structures as an abstraction

Seq as the unifying abstraction

Sequences are sequential (duh!)

Next:More choices

Page 10: Semantically coherent functional linear data structures

printfn "%A" (Seq.take 5 forecastDays |> Seq.toList)printfn "%A" (Seq.take 7 forecastDays |> Seq.toList)

> day 0 is forecast Sunny day 1 is forecast Cloudy day 2 is forecast Sunny day 3 is forecast Sunny day 4 is forecast Cloudy [Sunny; Cloudy; Sunny; Sunny; Cloudy] day 0 is forecast Sunny day 1 is forecast Sunny day 2 is forecast Sunny day 3 is forecast Sunny day 4 is forecast Sunny day 5 is forecast Sunny day 6 is forecast Cloudy [Sunny; Sunny; Sunny; Sunny; Sunny; Sunny; Cloudy]

Inconsistent!

Page 11: Semantically coherent functional linear data structures

LazyList: seq-like & List-likelet lazyWeatherList = LazyList.unfold NextState (Sunny, (new Random()), 0L)printfn "%A" (LazyList.take 3 lazyWeatherList)

> day 0 is forecast Sunny day 1 is forecast Sunny day 2 is forecast Cloudy [Sunny; Sunny; Cloudy]

printfn "%A" (LazyList.take 4 lazyWeatherList)

> day 3 is forecast Cloudy [Sunny; Sunny; Cloudy ; Cloudy]

Page 12: Semantically coherent functional linear data structures

Skip always evaluates

LazyList.ofSeq (seq {for i = 1 to 10 do yield (nextItem i)})|> LazyList.skip 2|> LazyList.take 2|> List.ofSeq

> item 1 item 2 item 3 item 4

Page 13: Semantically coherent functional linear data structures

O(1) Appendlet observedWeatherList =

LazyList.ofList [Sunny; Sunny; Cloudy; Cloudy; Rainy;]

let combinedWeatherList = LazyList.append observedWeatherList

lazyWeatherList

printfn "%A" (LazyList.skip 4 combinedWeatherList |> LazyList.take 3)> day 0 is forecast Rainy

day 1 is forecast Cloudy seq [Rainy; Rainy; Cloudy]

Observed Predicted

Page 14: Semantically coherent functional linear data structures

List - like

[ ]

Construct Deconstruct

Tail

Head

1

empty

::

…and the only data element accessible!

Page 15: Semantically coherent functional linear data structures

Vector

54321

Construct Deconstruct

Initial

Last

[ ]

empty

;;

Page 16: Semantically coherent functional linear data structures

Multiway Forest

Page 17: Semantically coherent functional linear data structures

Multiway Treetype 'a MultiwayTree = {Root: 'a; Children: 'a MultiwayForest}

with…

and 'a MultiwayForest = 'a MultiwayTree Vector

let inline create root children = {Root = root; Children = children}

let inline singleton x = create x Vector.empty

Page 18: Semantically coherent functional linear data structures

Queue ::

1 ;;

Deconstruct

Construct

DList ::

1 ;;

Construct Deconstruct

Construct

Tail

Head

Tail

Head

Page 19: Semantically coherent functional linear data structures

Breadth 1st Traversal

let inline breadth1stForest forest = let rec loop acc dl =match dl with| DList.Nil -> acc| DList.Cons(head, tail) ->

loop(Queue.conj head.Root acc)(DList.append tail (DList.ofSeq

head.Children))

loop Queue.empty (DList.ofSeq forest)

Page 20: Semantically coherent functional linear data structures

What areWe Missing?

We’ve seen

The right structure for the right job

Page 21: Semantically coherent functional linear data structures

RandomAccessList

54321

Construct Deconstruct

Tail

Head

[ ]

empty

::

Page 22: Semantically coherent functional linear data structures

Deque (double-ended queue)

5::

1

Head Tail

;;

Init LastConstruct Deconstruct

Construct Deconstruct

Page 23: Semantically coherent functional linear data structures

Heap (ordered)

::

1

Head Tail

Deconstruct

Construct

Graphics: http://www.turbosquid.com/3d-models/heap-gravel-max/668104

Page 24: Semantically coherent functional linear data structures

Deletions?

Page 25: Semantically coherent functional linear data structures

What Else?Random Stack

Purely Functional Circular Buffer

Questions?