2 people like it.

Better Pigeon/Akka actors

This time with recursive function through computation expression around continuations...

 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: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
#r @"C:\Development\GitHub\Pigeon\src\Pigeon\bin\Release\Akka.dll"
#r @"C:\Development\GitHub\Pigeon\src\Pigeon.FSharp\bin\Release\Akka.FSharp.dll"

open Akka.FSharp
open Akka.Actor


type IO<'msg> = | Input

type Cont<'m> =
    | Func of ('m -> Cont<'m>)

module Cont =
    let raw (Func f) = f
    let eff f m = m |> raw f

type ActorBuilder() =
    member this.Bind(m : IO<'msg>, f :'msg -> _) = 
        Func (fun m -> f m)
    member this.ReturnFrom(x) = x
    
    member this.Zero() = fun () -> ()

let actor = ActorBuilder()

type FunActor<'m>(actor: IO<'m> -> Cont<'m>) =
    inherit Actor()
    
    let mutable state = actor Input

    override x.OnReceive(msg) =
        let message = msg :?> 'm
        state <- Cont.eff state message



module Actor =
    let system name =
        ActorSystem.Create(name)

    let spawn (system:ActorSystem) (f: (IO<'m> -> Cont<'m>))  =
       system.ActorOf(Props(Deploy.Local, typeof<FunActor<'m>>, [f]))
      

let system = Actor.system "Actors"


type Message =
    | Inc of int
    | Dec of int
    | Stop

let a = 
    Actor.spawn system
    <| fun recv ->
        let rec loop s =
            actor {
                let! msg = recv
                printfn "%d" s
                match msg with
                | Inc n ->
                     return! loop (s + n)
                | Dec n -> 
                    return! loop (s - n)
                | Stop -> return! stop ()
            }
        and stop () = actor {
            let! _ = recv
            printfn "I'm stopped"
            return! stop()
            }
        loop 0

[0..10] |> List.iter(fun _ -> a <! Inc 2)
[0..10] |> List.iter (fun _ -> a <! Dec 1)
a <! Stop
[0..10] |> List.iter (fun _ -> a <! Inc 1)
namespace Microsoft.FSharp
type IO<'msg> = | Input

Full name: Script.IO<_>
union case IO.Input: IO<'msg>
type Cont<'m> = | Func of ('m -> Cont<'m>)

Full name: Script.Cont<_>
union case Cont.Func: ('m -> Cont<'m>) -> Cont<'m>
val raw : Cont<'a> -> ('a -> Cont<'a>)

Full name: Script.Cont.raw
val f : ('a -> Cont<'a>)
val eff : f:Cont<'a> -> m:'a -> Cont<'a>

Full name: Script.Cont.eff
val f : Cont<'a>
val m : 'a
Multiple items
type ActorBuilder =
  new : unit -> ActorBuilder
  member Bind : m:IO<'msg> * f:('msg -> Cont<'msg>) -> Cont<'msg>
  member ReturnFrom : x:'a -> 'a
  member Zero : unit -> (unit -> unit)

Full name: Script.ActorBuilder

--------------------
new : unit -> ActorBuilder
val this : ActorBuilder
member ActorBuilder.Bind : m:IO<'msg> * f:('msg -> Cont<'msg>) -> Cont<'msg>

Full name: Script.ActorBuilder.Bind
val m : IO<'msg>
val f : ('msg -> Cont<'msg>)
val m : 'msg
member ActorBuilder.ReturnFrom : x:'a -> 'a

Full name: Script.ActorBuilder.ReturnFrom
val x : 'a
member ActorBuilder.Zero : unit -> (unit -> unit)

Full name: Script.ActorBuilder.Zero
val actor : ActorBuilder

Full name: Script.actor
Multiple items
type FunActor<'m> =
  inherit obj
  new : actor:(IO<'m> -> Cont<'m>) -> FunActor<'m>
  override OnReceive : msg:'a -> 'b

Full name: Script.FunActor<_>

--------------------
new : actor:(IO<'m> -> Cont<'m>) -> FunActor<'m>
val actor : (IO<'m> -> Cont<'m>)
Multiple items
module Cont

from Script

--------------------
type Cont<'m> = | Func of ('m -> Cont<'m>)

Full name: Script.Cont<_>
override FunActor.OnReceive : msg:'a -> 'b

Full name: Script.FunActor`1.OnReceive
val system : name:'a -> 'b

Full name: Script.Actor.system
val name : 'a
val spawn : system:'a -> f:(IO<'m> -> Cont<'m>) -> 'b

Full name: Script.Actor.spawn
val system : 'a
val f : (IO<'m> -> Cont<'m>)
val typeof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val system : obj

Full name: Script.system
module Actor

from Script
type Message =
  | Inc of int
  | Dec of int
  | Stop

Full name: Script.Message
union case Message.Inc: int -> Message
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<_>
union case Message.Dec: int -> Message
union case Message.Stop: Message
val a : obj

Full name: Script.a
val recv : IO<Message>
val loop : (int -> Cont<Message>)
val s : int
val msg : Message
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val n : int
val stop : (unit -> Cont<Message>)
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val iter : action:('T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iter
Raw view Test code New version

More information

Link:http://fssnip.net/lW
Posted:10 years ago
Author:thinkbeforecoding
Tags: akka , pigeon , actors