Created
September 7, 2016 09:07
-
-
Save richardadalton/61fd9e02a34398c78c217c4fd311fdf5 to your computer and use it in GitHub Desktop.
A simple generic Command/Query Agent in F# using MailboxProcessor
This file contains 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 Message<'S> = | |
| Query of ('S -> unit) | |
| Command of ('S -> 'S) | |
| Kill | |
type CQAgent<'S>(state: 'S) = | |
let innerModel = | |
MailboxProcessor<Message<'S>>.Start(fun inbox -> | |
let rec messageLoop (state: 'S) = | |
async { | |
let! msg = inbox.Receive() | |
match msg with | |
| Query q -> | |
q state | |
return! messageLoop state | |
| Command c -> | |
let newState = c state | |
return! messageLoop(newState) | |
| Kill -> () | |
} | |
messageLoop state) | |
member this.Query<'T> (q: 'S -> 'T) = | |
innerModel.PostAndReply(fun chan -> Query(fun state -> | |
let res = q state | |
chan.Reply(res))) | |
member this.Command<'T> (c: 'S -> 'T * 'S) = | |
innerModel.PostAndReply(fun chan -> Command(fun state -> | |
let res, newState = c state | |
chan.Reply(res) | |
newState)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment