Arcadia


 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: 
open System.Threading
open System.Diagnostics

            // Input of value * changed
type Node = | Input of int ref * Event<unit>
            // Output of node1 * node2 * nodeFunction * initialValue * dirty * changed
            | Output of Node * Node * (int -> int -> int) * int ref * bool ref * Event<unit>

let rec eval (node : Node) : Async<int> =
    match node with
    |Input(n, _) -> async { return n.Value }
    |Output(n1,n2,f, initValue, dirty, _) ->
        async {
            if dirty.Value then
                let! v = Async.Parallel [ eval n1; eval n2 ]
                initValue := f v.[0] v.[1]
                dirty := false
            return initValue.Value }

let setValue (node : Node) (v : int) =
    match node with
    | Input(n, e) -> 
        n := v
        e.Trigger()
    | Output(_) -> failwith "cannot set value of output node"

let input i = Input(ref i, Event<unit>())
let func n1 n2 f = 
    let initValue = ref 0
    let dirty = ref true
    let event = Event<unit>()

    let getEvent (node : Node) = match node with Input(_, e) | Output(_, _, _, _, _, e) -> e
    (getEvent n1).Publish.Add(fun _ -> dirty := true; event.Trigger())
    (getEvent n2).Publish.Add(fun _ -> dirty := true; event.Trigger())

    Output(n1, n2, f, initValue, dirty, event)

let i1 = input 1
let i2 = input 3
let i3 = input 5

let n1 = func i1 i2 (fun x1 x2 -> printfn "*** eval n1, thread %i" Thread.CurrentThread.ManagedThreadId ; x1+x2)
let n2 = func i2 i3 (fun x1 x2 -> printfn "*** eval n2, thread %i" Thread.CurrentThread.ManagedThreadId ; x1+x2)
let n3 = func n1 n2 (fun x1 x2 -> printfn "*** eval n3, thread %i" Thread.CurrentThread.ManagedThreadId ; x1+x2)


let evalAsync (node : Node) =
    async { let! v = eval node in printfn "node value %i" v } |> Async.Start


evalAsync n3


setValue i1 100
namespace System
namespace System.Threading
namespace System.Diagnostics
type Node =
  | Input of int ref * Event<unit>
  | Output of Node * Node * (int -> int -> int) * int ref * bool ref * Event<unit>

Full name: Presentation.Node
union case Node.Input: int ref * Event<unit> -> Node
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
Multiple items
module Event

from Microsoft.FSharp.Control

--------------------
type Event<'T> =
  new : unit -> Event<'T>
  member Trigger : arg:'T -> unit
  member Publish : IEvent<'T>

Full name: Microsoft.FSharp.Control.Event<_>

--------------------
type Event<'Delegate,'Args (requires delegate and 'Delegate :> Delegate)> =
  new : unit -> Event<'Delegate,'Args>
  member Trigger : sender:obj * args:'Args -> unit
  member Publish : IEvent<'Delegate,'Args>

Full name: Microsoft.FSharp.Control.Event<_,_>

--------------------
new : unit -> Event<'T>

--------------------
new : unit -> Event<'Delegate,'Args>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
union case Node.Output: Node * Node * (int -> int -> int) * int ref * bool ref * Event<unit> -> Node
type bool = System.Boolean

Full name: Microsoft.FSharp.Core.bool
val eval : node:Node -> Async<int>

Full name: Presentation.eval
val node : Node
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
val n : int ref
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
property Ref.Value: int
val n1 : Node
val n2 : Node
val f : (int -> int -> int)
val initValue : int ref
val dirty : bool ref
property Ref.Value: bool
val v : int []
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
val setValue : node:Node -> v:int -> unit

Full name: Presentation.setValue
val v : int
val e : Event<unit>
member Event.Trigger : arg:'T -> unit
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val input : i:int -> Node

Full name: Presentation.input
val i : int
val func : n1:Node -> n2:Node -> f:(int -> int -> int) -> Node

Full name: Presentation.func
val event : Event<unit>
val getEvent : (Node -> Event<unit>)
val i1 : Node

Full name: Presentation.i1
val i2 : Node

Full name: Presentation.i2
val i3 : Node

Full name: Presentation.i3
val n1 : Node

Full name: Presentation.n1
val x1 : int
val x2 : int
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
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
property Thread.CurrentThread: Thread
property Thread.ManagedThreadId: int
val n2 : Node

Full name: Presentation.n2
val n3 : Node

Full name: Presentation.n3
val evalAsync : node:Node -> unit

Full name: Presentation.evalAsync
static member Async.Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
Fork me on GitHub