Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active August 29, 2015 14:19
Show Gist options
  • Save hodzanassredin/aaeb2def11d6f40c5627 to your computer and use it in GitHub Desktop.
Save hodzanassredin/aaeb2def11d6f40c5627 to your computer and use it in GitHub Desktop.
Simple reducers and Nessos streams in fsharp for blogpost
type OptionBuilder() =
member x.Bind(v,f) = Option.bind f v
member x.Return v = Some v
member x.ReturnFrom o = o
let opt = OptionBuilder()
//Clojure reducers
let reduceSeq reducingF start ss =
let mutable acc = start
for s in ss do
acc <- reducingF acc s
acc
let map f reducer = fun acc current -> reducer acc (f current)
let filter f reducer = fun acc current -> if f current then reducer acc current else acc
let dbl x = 2 * x
let even x = x % 2 = 0
let s = [1;2;3;4;5] |> Seq.ofList
let toListReducer acc current = current :: acc
let toSeqReducer acc current =
seq{
yield current
yield! acc
}
let mapNFilter reducer = filter even (map dbl reducer)
reduceSeq (mapNFilter toListReducer) [] s |> printfn "reducer strict list %A"
reduceSeq (mapNFilter toSeqReducer) Seq.empty s |> printfn "reducer lazy seq %A"
//Nessos Streams
//http://anirothan.github.io/StreamsPresentation/index.html#/15
type Stream<'T> = ('T -> unit) -> unit
let seqStream ss =
fun f ->
for s in ss do
f(s)
let streamToList stream =
let lst = ref []
let f v = lst := v :: !lst
stream f
lst
let streamMap mapf stream =
fun f -> mapf >> f |> stream
let streamFilter filterf stream =
let fn f v = if filterf v then f v else ()
fun f -> fn f |> stream
let streamMapNFilter stream = streamFilter even (streamMap dbl stream)
seqStream s |> streamMapNFilter |> streamToList |> printfn "Pull stream to list %A"
//http://hodzanassredin.github.io/2014/07/02/way-to-computation-expressions.html
//http://community.bartdesmet.net/blogs/bart/archive/2010/01/01/the-essence-of-linq-minlinq.aspx
//do dual
type PullStream<'T> = unit -> (unit -> 'T option)
let seqPullStream (ss:seq<'a>) =
fun () ->
let enum = ss.GetEnumerator()
fun () -> if enum.MoveNext() then Some(enum.Current) else None
let streamPullToList (stream : PullStream<'a>) =
let mutable lst = []
let enum = stream()
let mutable curr = enum()
while curr.IsSome do
lst <- curr.Value :: lst
curr <- enum()
lst
let streamPullMap mapf stream =
fun () ->
let enum = stream()
fun () -> match enum() with
| Some(res) -> Some(mapf res)
| None -> None
let streamPullFilter filterf stream =
fun () ->
let enum = stream()
fun () -> match enum() with
| Some(res) -> Some(mapf res)
| None -> None
let streamMapNFilter stream = streamFilter even (streamMap dbl stream)
seqStream s |> streamMapNFilter |> streamToList |> printfn "Pull stream to list %A"
[<EntryPoint>]
let main argv =
printfn "%A" argv
System.Console.ReadKey() |> ignore
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment