Skip to content

Instantly share code, notes, and snippets.

@richardadalton
Created September 7, 2016 09:07
Show Gist options
  • Save richardadalton/61fd9e02a34398c78c217c4fd311fdf5 to your computer and use it in GitHub Desktop.
Save richardadalton/61fd9e02a34398c78c217c4fd311fdf5 to your computer and use it in GitHub Desktop.
A simple generic Command/Query Agent in F# using MailboxProcessor
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