### FSharpPlus

Defines the basic operations over a monad, a concept from a branch of mathematics known as category theory. From the perspective of an F# programmer, however, it is best to think of a monad as an abstract datatype of actions. F#+ generic computation expressions provide a convenient syntax for writing monadic expressions.

## Minimal complete definition

• return x/result x
• (>>=) x f
static member Return (x: 'T) : 'Monad<'T>


Note: return can't be used outside computation expressions, use result instead.

## Other operations

• join
static member Join (x:'Monad<'Monad<'T>>) :'Monad<'T>


## Rules

return a >>= k = k a
m >>= return = m
m >>= (fun x -> k x >>= h) = (m >>= k) >>= h


## Related Abstractions

• Functor: Monads are automatically functors.

• Applicative : Monads are automatically applicatives.

## Concrete implementations

From F#

• seq<'T>
• list<'T>
• array<'T>
• option<'T>
• Lazy<'T>
• Async<'T>
• Result<'T,'U>
• Choice<'T,'U>
• 'Monoid * 'T
• Task<'T>
• 'R->'T
• ResizeArray<'T>

From F#+

## Examples

#r @"../../src/FSharpPlus/bin/Release/net45/FSharpPlus.dll"

open FSharpPlus
open FSharpPlus.Data

// Monads allow us to use our generic computation expressions

// This will return the list [11;21;12;22] which is both lists combined in different ways with the (+) operation
let lst11n21n12n22 =
let! x1 = [1;   2]
let! x2 = [10; 20]
return ((+) x1 x2) }

// This is the same example but with a non-empty list
let neLst11n21n12n22 =
let! x1 = { NonEmptyList.Head =  1; Tail =   }
let! x2 = { NonEmptyList.Head = 10; Tail =  }
return ((+) x1 x2)}

// And now an example with options
let some14 =
let! x1 = Some 4
let! x2 = tryParse "10"
return ((+) x1 x2) }

// ==================
//
// Monads do not compose directly, we need to use Monad Transformers

 let fn : ResultT>> = monad { let! x1 = lift ask let! x2 = if x1 > 0 then result 1 else ResultT (result (Error "Negative value")) return x1 + x2 } let x = (fn |> ResultT.run |> Reader.run) 10 // Result = Ok 11 let y = (fn |> ResultT.run |> Reader.run) -1 // Result = Error "Negative value" 
// The following example comes from Haskell
// async is used instead of IO

open System

// First let's define some functions we'll use later
let getLine    = async { return Console.ReadLine () }
let putStrLn x = async { printfn "%s" x }
let isValid s =
String.length s >= 8
&& String.exists Char.IsLetter s
&& String.exists Char.IsNumber s
&& String.exists Char.IsPunctuation s

let decodeError = function
| -1 -> "Password not valid"
| _  -> "Unknown"

// Now the following functions compose the Error monad with the Async one.

let! s = liftAsync getLine
if isValid s then return s
else return! throw -1}
</catch/>
(fun s -> throw ("The error was: " + decodeError s))

//do! lift <| putStrLn "Storing in database..."
return value}

// After getting used to monadic CEs it's natural
// to feel the need to combine monads
// (from https://stackoverflow.com/a/37900264 )

module CombineWriterWithResult =

let divide5By = function
| 0.0 -> Error "Divide by zero"
| x   -> Ok (5.0 / x)

let eitherConv logSuccessF logFailF f v =
ResultT <|
match f v with
| Ok a -> Writer(Ok a, ["Success: " + logSuccessF a])
| Error b -> Writer(Error b, ["ERROR: "   + logFailF b])

let! x = eitherConv (sprintf "%f") (sprintf "%s") divide5By 6.0
let! y = eitherConv (sprintf "%f") (sprintf "%s") divide5By 3.0
let! z = eitherConv (sprintf "%f") (sprintf "%s") divide5By 0.0
return (x, y, z) }

let (_, log) = ew |> ResultT.run |> Writer.run

// You can also stack monad transformers.

// For example, below we are stacking them like:
// type Example = ReaderT<DateTime, ResultT<Writer<string list, Result<string * string * string, string>>>>)

// Catch and throw is generic over all monad transformers in F#+ so catch works in this example
// because there is a Result in the stack. We use it here to consolidate Result's 'TError.

let divide5By : float -> Result<float, string> = function
| 0.0 -> Error "Divide by zero"
| x   -> Ok (5.0 / x)

let otherDivide5By : float -> Result<float, unit>  = function
| 0.0 -> Error ()
| x   -> Ok (5.0 / x)

let eitherConv f v =
ReaderT <| fun (now : System.DateTime) ->
ResultT <|
match f v with
| Ok a    -> Writer(Ok a,    [sprintf "Success at %s: %A" (now.ToString "o") a])
| Error b -> Writer(Error b, [sprintf "ERROR at %s: %A"   (now.ToString "o") b])

let! w = eitherConv divide5By       6.0
let! x = eitherConv divide5By       3.0
let! y = eitherConv divide5By       0.0
let! z = eitherConv otherDivide5By  0.0 </catch/> (throw << (fun _ -> "Unknown error"))

return (w, x, y, z) }

let run expr = ReaderT.run expr >> ResultT.run >> Writer.run

let (_, log) = run divide DateTime.UtcNow

// Many popular F# libraries are in fact an instantiation of a specific monad combination.
// The following example demonstrate how to code a mini-Suave lib in a few lines

module Suave =
// setup something that reminds us of what Suave can work with
// this is an overly simplified model of Suave in order to show how OptionT can be used
// in conjunction with generic Kleisli composition (fish) operator
type WebPart<'a> = 'a -> OptionT<Async<'a option>>
let inline succeed x = async.Return (Some x)

module WebPart =
/// Comment from <a href="https://github.com/SuaveIO/suave/blob/v2.4.3/src/Suave/WebPart.fsi#L39-L42">WebPart.fsi</a>
/// Entry-point for composing the applicative routes of the http application,
/// by iterating the options, applying the context, arg, to the predicate
/// from the list of options, until there's a match/a Some(x) which can be
/// run.
let choose (options: WebPart<'a> list) = fun x -> choice (List.map ((|>) x) options)

module Http =
type HttpResponse = { status: int; content: string }
type HttpRequest  = { url: Uri; method: string }
type HttpContext  = { request: HttpRequest; response: HttpResponse }

module Successful =
open Http
let private withStatusCode statusCode s =
OptionT << fun ctx -> { ctx with response = { ctx.response with status = statusCode; content = s }} |> succeed
let OK s = withStatusCode 200 s
let BAD_REQUEST s = withStatusCode 400 s

module Filters =
open Http
let method (m: string) =
OptionT << fun (x: HttpContext) -> async.Return (if (m = x.request.method) then Some x else None)
let GET  (x : HttpContext) = method "GET" x
let POST (x : HttpContext) = method "POST" x

let path s =
OptionT << fun (x: HttpContext) -> async.Return (if (s = x.request.url.AbsolutePath) then Some x else None)

// Stub implementations: here you can plug Fleece or another similar Json library
let toJson o : string  = failwith "Not implemented"
let ofJson (s: string) = failwith "Not implemented"

module Request =
let tryGet _s (_r: Http.HttpRequest) = Ok "FORM VALUE"

let authenticated (f: Http.HttpContext -> int -> OptionT<Async<'a option>>) =
// we assume that authenticated executes f only if auth, otherwise returns 401
// we fake it as:
fun (ctx: Http.HttpContext) -> f ctx -1

// Usage:
open Successful
open Filters
type Note = { id: int; text: string }
type NoteList = { notes: Note list; offset: int; chunk: int; total: int }
type IDb =
abstract member getUserNotes: int -> Async<NoteList>
abstract member addUserNote: int -> string -> Async<Note>
type OverviewViewModel = { myNotes: Note list }
let app (db: IDb) =
let overview =
GET >=> (authenticated <| fun ctx userId ->
let! res = lift (db.getUserNotes userId)
let ovm = toJson { myNotes = res.notes }
return! OK ovm ctx
})
let register =
POST >=> (authenticated <| fun ctx userId ->
match ctx.request |> Request.tryGet "text" with
| Ok text ->
let! newNote = lift (db.addUserNote userId text)
let rvm = toJson newNote
return! OK rvm ctx
| Error msg ->
})
WebPart.choose [ path "/" >=> (OK "/")
path "/note" >=> register
path "/notes" >=> overview ]

namespace FSharpPlus
namespace FSharpPlus.Data
val lst11n21n12n22 : int list
val x1 : int
val x2 : int
val neLst11n21n12n22 : NonEmptyList<int>
Multiple items
module NonEmptyList

from FSharpPlus.Data

--------------------
type NonEmptyList<'t> =
Tail: 't list }
interface NonEmptySeq<'t>
interface IEnumerable
interface IEnumerable<'t>
member GetSlice : (int option * int option -> NonEmptyList<'t>)
member Item : (int -> 't)
member Length : int
static member Choice : source:NonEmptyList<'Alt<'T>> -> 'Alt<'T> (requires member IsAltLeftZero and member ( <|> ))
static member Duplicate : s:NonEmptyList<'a> * _impl:Duplicate -> NonEmptyList<NonEmptyList<'a>>
...
val some14 : int option
union case Option.Some: Value: 'T -> Option<'T>
val tryParse : value:string -> 'b option (requires member TryParse)
namespace System
val getLine : Async<string>
val async : AsyncBuilder
type Console =
static member BackgroundColor : ConsoleColor with get, set
static member Beep : unit -> unit + 1 overload
static member BufferHeight : int with get, set
static member BufferWidth : int with get, set
static member CapsLock : bool
static member Clear : unit -> unit
static member CursorLeft : int with get, set
static member CursorSize : int with get, set
static member CursorTop : int with get, set
static member CursorVisible : bool with get, set
...
val putStrLn : x:string -> Async<unit>
val x : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
val isValid : s:string -> bool
val s : string
Multiple items
type String =
new : value:char[] -> string + 8 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool + 3 overloads
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 3 overloads
member EnumerateRunes : unit -> StringRuneEnumerator
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
...

--------------------
String(value: char []) : String
String(value: nativeptr<char>) : String
String(value: nativeptr<sbyte>) : String
String(c: char, count: int) : String
String(value: char [], startIndex: int, length: int) : String
String(value: nativeptr<char>, startIndex: int, length: int) : String
String(value: nativeptr<sbyte>, startIndex: int, length: int) : String
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : String
val length : str:string -> int
val exists : predicate:(char -> bool) -> str:string -> bool
type Char =
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 1 overload
static val MaxValue : char
static val MinValue : char
static member ConvertFromUtf32 : utf32:int -> string
static member ConvertToUtf32 : highSurrogate:char * lowSurrogate:char -> int + 1 overload
static member GetNumericValue : c:char -> float + 1 overload
...
end
Char.IsLetter(c: char) : bool
Char.IsLetter(s: string, index: int) : bool
Char.IsNumber(c: char) : bool
Char.IsNumber(s: string, index: int) : bool
Char.IsPunctuation(c: char) : bool
Char.IsPunctuation(s: string, index: int) : bool
val decodeError : _arg1:int -> string
Multiple items

--------------------
module ResultT

from FSharpPlus.Data

--------------------
[<Struct>]
static member Catch : ResultT<'MonadError<'E1,'T>> * f:('E1 -> ResultT<'Monad<Result<'T,'E2>>>) -> ResultT<'Monad<Result<'T,'E2>>> (requires member ( >>= ) and member Return)
static member Delay : body:(unit -> ResultT<'Monad<'Result<'T,'E>>>) -> ResultT<'a2> (requires member Delay)
static member LiftAsync : x:Async<'T> -> ResultT<'MonadAsync<'T>> (requires member Return and member ( >>= ) and member Map and member LiftAsync)
static member Listen : m:ResultT<'a1> -> ResultT<'MonadWriter<'Monoid,Result<'T*'Monoid,'E>>> (requires member ( >>= ) and member Return and member Listen)
static member Local : ResultT<'MonadReader<'R2,Result<'R2,'E>>> * f:('R1 -> 'R2) -> ResultT<'a4> (requires member Local)
static member Pass : m:ResultT<'a1> -> ResultT<'MonadWriter<'Monoid,Result<'T,'E>>> (requires member ( >>= ) and member Map and member Return and member Pass and member Return)
static member Put : x:'S -> ResultT<'MonadState<'S,Result<_,'E>>> (requires member Return and member ( >>= ) and member Map and member Put)
static member Return : x:'T -> ResultT<'Monad<'Result<'T,'E>>> (requires member Return)
static member Tell : w:'Monoid -> ResultT<'Writer<'Monoid,Result<unit,'E>>> (requires member Return and member ( >>= ) and member Map and member Tell)
...
val liftAsync : x:Async<'T> -> 'MonadAsync<'T> (requires member LiftAsync)
val throw : error:'E -> ''MonadError<'E,'T> (requires member Throw)
val s : int
val value : string
val divide5By : _arg1:float -> Result<float,string>
union case Result.Error: ErrorValue: 'TError -> Result<'T,'TError>
val x : float
union case Result.Ok: ResultValue: 'T -> Result<'T,'TError>
val eitherConv : logSuccessF:('a -> string) -> logFailF:('b -> string) -> f:('c -> Result<'a,'b>) -> v:'c -> ResultT<Writer<string list,Result<'a,'b>>>
val logSuccessF : ('a -> string)
val logFailF : ('b -> string)
val f : ('c -> Result<'a,'b>)
val v : 'c
val a : 'a
Multiple items
union case Writer.Writer: ('t * 'monoid) -> Writer<'monoid,'t>

--------------------
module Writer

from FSharpPlus.Data

--------------------
[<Struct>]
type Writer<'monoid,'t> =
| Writer of ('t * 'monoid)
static member Extract : Writer<'T,'W> -> 'T
static member Listen : m:Writer<'Monoid,'T> -> Writer<'Monoid,('T * 'Monoid)>
static member Pass : m:Writer<'Monoid,('T * ('Monoid -> 'Monoid))> -> Writer<'Monoid,'T>
static member Return : x:'T -> Writer<'Monoid,'T> (requires member Zero)
static member Tell : w:'Monoid -> Writer<'Monoid,unit>
static member ( =>> ) : g:Writer<'T,'W> * f:(Writer<'T,'W> -> 'U) -> Writer<'U,'W>
static member ( >>= ) : x:Writer<'Monoid,'T> * f:('T -> Writer<'Monoid,'U>) -> Writer<'Monoid,'U> (requires member ( + ))
static member ( <*> ) : f:Writer<'Monoid,('T -> 'U)> * x:Writer<'Monoid,'T> -> Writer<'Monoid,'U> (requires member ( + ))
val b : 'b
val ew : ResultT<Writer<string list,Result<(float * float * float),string>>>
val sprintf : format:Printf.StringFormat<'T> -> 'T
val y : float
val z : float
val log : string list
val run : Writer<'Monoid,'T> -> 'T * 'Monoid
Multiple items
val float : value:'T -> float (requires member op_Explicit)

--------------------
type float = Double

--------------------
type float<'Measure> = float
Multiple items
module Result

from FSharpPlus.Data

--------------------
module Result

from FSharpPlus

--------------------
module Result

from Microsoft.FSharp.Core

--------------------
[<Struct>]
type Result<'T,'TError> =
| Ok of ResultValue: 'T
| Error of ErrorValue: 'TError
Multiple items
val string : value:'T -> string

--------------------
type string = String
val otherDivide5By : _arg1:float -> Result<float,unit>
type unit = Unit
val eitherConv : f:('a -> Result<'b,'c>) -> v:'a -> ReaderT<DateTime,ResultT<Writer<string list,Result<'b,'c>>>>
val f : ('a -> Result<'b,'c>)
val v : 'a
Multiple items

--------------------

from FSharpPlus.Data

--------------------
[<Struct>]
...
val now : DateTime
Multiple items
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end

--------------------
DateTime ()
DateTime(ticks: int64) : DateTime
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
DateTime(year: int, month: int, day: int) : DateTime
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : DateTime
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : DateTime
val a : 'b
val b : 'c
val divide : ReaderT<DateTime,ResultT<Writer<string list,Result<(float * float * float * float),string>>>>
val w : float
val run : expr:ReaderT<'a,ResultT<Writer<'b,'c>>> -> ('a -> 'c * 'b)
property DateTime.UtcNow: DateTime with get
module Suave

type WebPart<'a> = 'a -> OptionT<Async<'a option>>
Multiple items

--------------------
module OptionT

from FSharpPlus.Data

--------------------
[<Struct>]
static member Delay : body:(unit -> OptionT<'Monad<option<'T>>>) -> OptionT<'Monad<option<'T>>> (requires member Delay)
static member LiftAsync : x:Async<'T> -> OptionT<'MonadAsync<'T>> (requires member Return and member ( >>= ) and member Map and member LiftAsync)
static member Listen : m:OptionT<'a1> -> OptionT<''MonadWriter<'Monoid, option<'T>>> (requires member ( >>= ) and member Return and member Listen)
static member Local : OptionT<'MonadReader<'R2,'T>> * f:('R1 -> 'R2) -> OptionT<'a4> (requires member Local)
static member Pass : m:OptionT<'a1> -> OptionT<'MonadWriter<'Monoid, option<'T>>> (requires member ( >>= ) and member Map and member Return and member Pass and member Return)
static member Put : x:'S -> OptionT<'MonadState<unit,'S>> (requires member Return and member ( >>= ) and member Map and member Put)
static member Return : x:'T -> OptionT<'Monad<option<'T>> (requires member Return)
static member Tell : w:'Monoid -> OptionT<'MonadWriter<'Monoid, unit>> (requires member Return and member ( >>= ) and member Map and member Tell)
...
Multiple items
module Async

from FSharpPlus

--------------------
type Async =
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
...

--------------------
type Async<'T> =
Multiple items
val option : f:('g -> 'h) -> n:'h -> _arg1:'g option -> 'h

--------------------
type 'T option = Option<'T>
val succeed : x:'a -> Async<'a option>
val x : 'a
val choose : options:WebPart<'a> list -> x:'a -> OptionT<Async<'a option>>

Comment from <a href="https://github.com/SuaveIO/suave/blob/v2.4.3/src/Suave/WebPart.fsi#L39-L42">WebPart.fsi</a>
Entry-point for composing the applicative routes of the http application,
by iterating the options, applying the context, arg, to the predicate
from the list of options, until there's a match/a Some(x) which can be
run.
val options : WebPart<'a> list
type 'T list = List<'T>
val choice : x:'Foldable<'Alternative<'T>> -> 'Alternative<'T>> (requires member Choice)
Multiple items
module List

from FSharpPlus.Data

--------------------
module List

from FSharpPlus

--------------------
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
...
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
type HttpResponse =
{ status: int
content: string }
HttpResponse.status: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
HttpResponse.content: string
type HttpRequest =
{ url: Uri
method: string }
HttpRequest.url: Uri
Multiple items
type Uri =
new : uriString:string -> Uri + 5 overloads
member AbsolutePath : string
member AbsoluteUri : string
member Authority : string
member DnsSafeHost : string
member Equals : comparand:obj -> bool
member Fragment : string
member GetComponents : components:UriComponents * format:UriFormat -> string
member GetHashCode : unit -> int
member GetLeftPart : part:UriPartial -> string
...

--------------------
Uri(uriString: string) : Uri
Uri(uriString: string, uriKind: UriKind) : Uri
Uri(baseUri: Uri, relativeUri: string) : Uri
Uri(baseUri: Uri, relativeUri: Uri) : Uri
type HttpContext =
{ request: HttpRequest
response: HttpResponse }
HttpContext.request: HttpRequest
HttpContext.response: HttpResponse
module Http

val private withStatusCode : statusCode:int -> s:string -> (HttpContext -> OptionT<Async<HttpContext option>>)
val statusCode : int
val ctx : HttpContext
val OK : s:string -> (HttpContext -> OptionT<Async<HttpContext option>>)
val BAD_REQUEST : s:string -> (HttpContext -> OptionT<Async<HttpContext option>>)
val m : string
val x : HttpContext
union case Option.None: Option<'T>
val GET : x:HttpContext -> OptionT<Async<HttpContext option>>
val POST : x:HttpContext -> OptionT<Async<HttpContext option>>
val path : s:string -> (HttpContext -> OptionT<Async<HttpContext option>>)
val toJson : o:'a -> string
val o : 'a
val failwith : message:string -> 'T
val ofJson : s:string -> 'a
val tryGet : _s:'a -> _r:Http.HttpRequest -> Result<string,'b>
val _s : 'a
val _r : Http.HttpRequest
val authenticated : f:(Http.HttpContext -> int -> OptionT<Async<'a option>>) -> ctx:Http.HttpContext -> OptionT<Async<'a option>>
val f : (Http.HttpContext -> int -> OptionT<Async<'a option>>)
val ctx : Http.HttpContext
module Successful

module Filters

type Note =
{ id: int
text: string }
Note.id: int
Note.text: string
type NoteList =
{ notes: Note list
offset: int
chunk: int
total: int }
NoteList.notes: Note list
NoteList.offset: int
NoteList.chunk: int
NoteList.total: int
type IDb =
interface
abstract member addUserNote : int -> string -> Async<Note>
abstract member getUserNotes : int -> Async<NoteList>
end
type OverviewViewModel =
{ myNotes: Note list }
OverviewViewModel.myNotes: Note list
val app : db:IDb -> (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)
val db : IDb
val overview : (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)
val GET : x:Http.HttpContext -> OptionT<Async<Http.HttpContext option>>
val userId : int
val res : NoteList
val ovm : string
val OK : s:string -> (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)
val register : (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)
val POST : x:Http.HttpContext -> OptionT<Async<Http.HttpContext option>>
module Request