Skip to content

Instantly share code, notes, and snippets.

@Thorium
Forked from mattpodwysocki/gist:165605
Created April 18, 2012 21:11
Show Gist options
  • Save Thorium/2416591 to your computer and use it in GitHub Desktop.
Save Thorium/2416591 to your computer and use it in GitHub Desktop.
IObservable<T> is close to Async<T>, so why not: F# obs { ... } as async { ... }
#I @"C:\Tools\System.Reactive"
#r "System.Core.dll"
#r "System.Reactive.dll"
type observable<'a> = System.Collections.Generic.IObservable<'a>
type observer<'a> = System.Collections.Generic.IObserver<'a>
module Observable =
open System
open System.Linq
let of_seq : seq<'a> -> observable<'a> = Observable.ToObservable
let empty<'a> : observable<'a> = Observable.Empty<'a>()
let length : observable<'a> -> int = Observable.Count
let map selector source =
Observable.Select(source, Func<_,_>(selector))
let filter pred source =
Observable.Where(source, Func<_,_>(pred))
let collect selector source =
Observable.SelectMany(source, Func<_,_>(selector))
let subscribe (observer:observer<'a>) (source:observable<'a>) : IDisposable =
source.Subscribe(observer)
let createAction (onNext:'a -> unit) (onError:exn -> unit) (onCompleted : unit -> unit) =
Observer.Create(Action<_>(onNext), Action<exn>(onError), Action(onCompleted))
let until other source =
Observable.Until(source, other)
let fromEvent<'e when 'e :> EventArgs> (target:obj) (eventName:string) =
Observable.FromEvent<'e>(target, eventName)
let partition pred source =
(source |> filter pred, source |> filter (not << pred))
let returnObs = Observable.Return
open System
open System.Collections.Generic
open System.Windows.Forms
type System.Windows.Forms.Control with
member this.MouseDownEvent : observable<Event<MouseEventArgs>> = Observable.fromEvent<MouseEventArgs> this "MouseDown"
member this.MouseMoveEvent : observable<Event<MouseEventArgs>> = Observable.fromEvent<MouseEventArgs> this "MouseMove"
member this.MouseUpEvent : observable<Event<MouseEventArgs>> = Observable.fromEvent<MouseEventArgs> this "MouseUp"
type ObservableBuilder() =
member this.Delay(f) = f()
member this.Bind(x, f) = Observable.collect f x
member this.Zero() = Observable.empty
member this.Return(x) = Observable.returnObs x
let obs = new ObservableBuilder()
let draggingEvent (form:Form) =
obs { let! md = form.MouseDownEvent
return! form.MouseMoveEvent |> Observable.until form.MouseUpEvent }
let form = new Form(Visible=true, TopMost = true)
let over, under =
draggingEvent form
|> Observable.map (fun evt -> evt.EventArgs.X, evt.EventArgs.Y)
|> Observable.partition (fun (x,y) -> x > 100 && y > 100)
let od =
ObservableExtensions.Subscribe(over, Action<_>(fun (x,y) -> printfn "Over(%d,%d)" x y))
let ud =
ObservableExtensions.Subscribe(under, Action<_>(fun (x,y) -> printfn "Under(%d,%d)" x y))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment