Skip to content

Commit

Permalink
Merge pull request SuaveIO#694 from wallymathieu/webpart-bind
Browse files Browse the repository at this point in the history
Some minor comments to fix SuaveIO#691
  • Loading branch information
haf authored Apr 15, 2018
2 parents 51a8f31 + ee4186b commit 6525334
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
23 changes: 16 additions & 7 deletions src/Suave/WebPart.fs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
[<AutoOpen>]
module Suave.WebPart
(*
SuaveTask of 'a is defined as `Async<'a option>`. It's implied that by returning None, the SuaveTask expects Suave to
continue on to the next (in the `choose` below). Another name for `SuaveTask` is `AsyncOption` as can be seen in the
builder definition below.
type WebPart<'a> = 'a -> Async<'a option>
WebPart of 'a is defined as a function that takes 'a and returns SuaveTask of 'a or AsyncOption of 'a
let inline succeed x = async.Return (Some x)
WebPart without a specific type parameter is understood as WebPart of HttpContext.
*)
type WebPart<'a> = 'a -> Async<'a option>
// WebPart
let inline succeed x = async.Return (Some x)
// SuaveTask
let fail<'a> : Async<'a option> = async.Return (Option<'a>.None)

// WebPart
let never : WebPart<'a> = fun x -> fail

// Operates on SuaveTask
let bind (f: 'a -> Async<'b option>) (a: Async<'a option>) = async {
let! p = a
match p with
Expand All @@ -18,7 +27,7 @@ let bind (f: 'a -> Async<'b option>) (a: Async<'a option>) = async {
let r = f q
return! r
}

// Operates on SuaveTask
let compose (first : 'a -> Async<'b option>) (second : 'b -> Async<'c option>)
: 'a -> Async<'c option> =
fun x ->
Expand All @@ -38,7 +47,7 @@ let rec choose (options : WebPart<'a> list) : WebPart<'a> =
match options with
| [] -> return None
| p :: tail ->
let! res = p arg
let! res = p arg
match res with
| Some x -> return Some x
| None -> return! choose tail arg
Expand All @@ -56,7 +65,7 @@ let rec inject (postOp : WebPart<'a>) (pairs : (WebPart<'a> * WebPart<'a>) list)
| None -> return! inject postOp tail arg
}

let inline warbler f a = f a a
let inline warbler f a = f a a

let inline cnst x = fun _ -> x

Expand Down
13 changes: 7 additions & 6 deletions src/Suave/WebPart.fsi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[<AutoOpen>]
module Suave.WebPart

/// Takes 'a and returns SuaveTask of 'a
/// SuaveTask is also known as AsyncOption
type WebPart<'a> = 'a -> Async<'a option>

val inline succeed : WebPart<'a>
Expand All @@ -9,11 +10,11 @@ val fail<'a> : Async<'a option>

val never : WebPart<'a>

/// Classic bind
/// Classic bind (for SuaveTask)
val bind : f:('a -> Async<'b option>) -> a: Async<'a option> -> Async<'b option>

/// Left-to-right Kleisli composition.
val compose : first:('a -> Async<'b option>) -> second:('b -> Async<'c option>) -> 'a -> Async<'c option>
/// Left-to-right Kleisli composition (for SuaveTask).
val compose : first:('a -> Async<'b option>) -> second:('b -> Async<'c option>) -> 'a -> Async<'c option>

type AsyncOptionBuilder =
new : unit -> AsyncOptionBuilder
Expand Down Expand Up @@ -46,11 +47,11 @@ val choose : options:WebPart<'a> list -> WebPart<'a>
/// +------------+ +--------------+
/// | url "/a" +----------+ +---------+ cont1 |
/// +------------+ | | +--------------+
/// | |
/// | |
/// +-------------+ | +----------+ | +--------------+
/// | url "/b" +---------+-------+ injected +----+---------+ cont2 |
/// +-------------+ | +----------+ | +--------------+
/// | |
/// | |
/// +-------------+ | | +--------------+
/// | url "/b" +---------+ +---------+ cont3 |
/// +-------------+ +--------------+
Expand Down

0 comments on commit 6525334

Please sign in to comment.