Skip to content

Commit

Permalink
evented operators and traversal (#68)
Browse files Browse the repository at this point in the history
Co-authored-by: Radu Popovici <[email protected]>
  • Loading branch information
oncicaradupopovici and Radu Popovici authored Mar 13, 2020
1 parent 1b8eab4 commit 83405db
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 28 deletions.
13 changes: 0 additions & 13 deletions src/Core/NBB.Core.Effects.FSharp/Effects.fs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,6 @@ type Effect<'T> with
static member (>>=) (x,f) = Effect.bind f x
static member (<*>) (f,x) = Effect.apply f x

//module Effect =
// let bind func eff = Effect.Bind(eff, Func<'a, IEffect<'b>>(func))
// let map func eff = Effect.Map(Func<'a, 'b>(func), eff)
// let apply (func: IEffect<'a->'b>) eff = Effect.Apply(map (fun fn -> Func<'a,'b>(fn)) func, eff)
// let pure' x = Effect.Pure x
// let return' = pure'
// let ignore eff = map (fun _ -> ()) eff

// let composeK f g x = bind g (f x)
// let lift2 f = map f >> apply

// let interpret<'a> (interpreter:IInterpreter) eff = interpreter.Interpret<'a>(eff) |> Async.AwaitTask

module EffectBuilder =
type EffectBuilder() =
member _.Bind(eff, func) = Effect.bind func eff
Expand Down
40 changes: 25 additions & 15 deletions src/Core/NBB.Core.Evented.FSharp/Evented.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ module Evented =
let pure' value = Evented(value, [])
let return' = pure'

//let composeK f g x = bind g (f x)
let composeK f g x = bind g (f x)

//let lift2 f = map f >> apply
let lift2 f = map f >> apply

type Evented<'a, 'e> with
static member Map (x, f) = Evented.map f x
Expand All @@ -35,16 +35,26 @@ module EventedBuilder =
module Events =
let evented = new EventedBuilder.EventedBuilder()

//let (<!>) = Evented.map
//let (<*>) = Evented.apply
//let (>>=) evented func = Evented.bind func evented
//let (>=>) = Evented.composeK

//module List =
// let traverseEvented f list =
// let cons head tail = head :: tail
// let initState = Evented.pure' []
// let folder head tail = Evented.pure' cons <*> (f head) <*> tail
// List.foldBack folder list initState

// let sequenceEvented list = traverseEvented id list
let (<!>) = Evented.map
let (<*>) = Evented.apply
let (>>=) evented func = Evented.bind func evented
let (>=>) = Evented.composeK

[<RequireQualifiedAccess>]
module List =
let traverseEvented f list =
let cons head tail = head :: tail
let initState = Evented.pure' []
let folder head tail = Evented.pure' cons <*> (f head) <*> tail
List.foldBack folder list initState

let sequenceEvented list = traverseEvented id list

[<RequireQualifiedAccess>]
module Result =
let traverseEvented f result =
match result with
| Error err -> Evented.pure' (Error err)
| Ok v -> Evented.map Ok (f v)

let sequenceEvented result = traverseEvented id result
34 changes: 34 additions & 0 deletions test/UnitTests/Core/NBB.Core.Evented.FSharp.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,38 @@ let ``Evented workflow test`` () =

entity|> should equal (AggRoot 2)
events|> should equal [Added; Updated]


[<Fact>]
let ``Pure evented values should contain no events`` () =
let (Evented(_, events)) =
evented {
return 1
}

events|> should equal []

[<Fact>]
let ``List traverse evented should accumulate events`` () =
let xs = [1;2]
let fn = fun i ->
match i with
|1 -> Evented (1,[Added])
|_ -> Evented (2,[Updated])

let (Evented(_, events)) = xs |> List.traverseEvented fn

events|> should equal [Added;Updated]

[<Fact>]
let ``List sequence evented should accumulate events`` () =
let fn = fun i ->
match i with
|1 -> Evented (1,[Added])
|_ -> Evented (2,[Updated])
let xs = [1;2] |> List.map fn

let (Evented(_, events)) = xs |> List.sequenceEvented

events|> should equal [Added;Updated]

0 comments on commit 83405db

Please sign in to comment.