Last active
          August 29, 2015 14:19 
        
      - 
      
- 
        Save hodzanassredin/aaeb2def11d6f40c5627 to your computer and use it in GitHub Desktop. 
    Simple reducers and Nessos streams in fsharp for blogpost
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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