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.
return x
/ result x
(>>=) x f
static member Return (x: 'T) : 'Monad<'T>
static member (>>=) (x: 'Monad<'T>, f: 'T -> 'Monad<'U>) : 'Monad<'U>
Note: return
can't be used outside computation expressions, use result
instead.
static member Join (x: 'Monad<'Monad<'T>>) : 'Monad<'T>
return a >>= k = k a
m >>= return = m
m >>= (fun x -> k x >>= h) = (m >>= k) >>= h
From F#
seq<'T>
list<'T>
array<'T>
option<'T>
voption<'T>
Lazy<'T>
Async<'T>
Result<'T,'U>
Choice<'T,'U>
'Monoid * 'T
struct ('Monoid * 'T)
Task<'T>
ValueTask<'T>
'R->'T
ResizeArray<'T>
From F#+
Identity<'T>
Cont<'R,'T>
ContT<'R,'T>
Reader<'R,'T>
ReaderT<'R,'Monad<'T>>
Writer<'Monoid,'T>
WriterT<'Monad<'T * 'Monoid>>
State<'S,'T * 'S>
StateT<'S,'Monad<'T * 'S>>
OptionT<'Monad<option<'T>>
ValueOptionT<'Monad<voption<'T>>
SeqT<'Monad<seq<'T>>
ListT<'Monad<list<'T>>
ResultT<'Monad<Result<'T,'TError>>
ChoiceT<'Monad<Choice<'T,'TError>>
Free<'Functor<'T>,'T>
NonEmptyList<'T>
-
DList<'T>
Suggest another concrete implementation
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 =
monad {
let! x1 = [1; 2]
let! x2 = [10; 20]
return ((+) x1 x2) }
// This is the same example but with a non-empty list
let neLst11n21n12n22 =
monad {
let! x1 = { NonEmptyList.Head = 1; Tail = [2] }
let! x2 = { NonEmptyList.Head = 10; Tail = [20] }
return ((+) x1 x2)}
// And now an example with options
let some14 =
monad {
let! x1 = Some 4
let! x2 = tryParse "10"
return ((+) x1 x2) }
// MONAD TRANSFORMERS
// ==================
//
// Monads do not compose directly, we need to use Monad Transformers
let fn : ResultT<Reader<int,Result<_,string>>> =
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<int,string> = Ok 11
let y = (fn |> ResultT.run |> Reader.run) -1
// Result<int,string> = 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 getValidPassword : ResultT<_> =
monad {
let! s = liftAsync getLine
if isValid s then return s
else return! throw -1}
</catch/>
(fun s -> throw ("The error was: " + decodeError s))
let askPassword = monad {
do! lift <| putStrLn "Insert your new password:"
let! value = getValidPassword
//do! lift <| putStrLn "Storing in database..."
return value}
//try -> Async.RunSynchronously (ResultT.run askPassword)
// 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 ew = monad {
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.
// A monad transformer and a monad is itself a monad, so you can pass that into another monad transformer.
// 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.
module CombineReaderWithWriterWithResult =
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 divide = monad {
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 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 ->
monad {
let! res = lift (db.getUserNotes userId)
let ovm = toJson { myNotes = res.notes }
return! OK ovm ctx
})
let register =
POST >=> (authenticated <| fun ctx userId ->
monad {
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 ->
return! BAD_REQUEST msg ctx
})
choice [
path "/" >=> (OK "/")
path "/note" >=> register
path "/notes" >=> overview
]
namespace FSharpPlus
namespace FSharpPlus.Data
val lst11n21n12n22: int list
val monad<'monad<'t>> : MonadFxBuilder<'monad<'t>>
<summary>
Creates a (lazy) monadic computation expression with side-effects (see http://fsprojects.github.io/FSharpPlus/computation-expressions.html for more information)
</summary>
val x1: int
val x2: int
val neLst11n21n12n22: NonEmptyList<int>
Multiple items
module NonEmptyList
from FSharpPlus.Data
<summary>
Basic operations on NonEmptyList
</summary>
--------------------
type NonEmptyList<'t> =
{
Head: 't
Tail: 't list
}
interface NonEmptySeq<'t>
interface IReadOnlyList<'t>
interface IReadOnlyCollection<'t>
interface IEnumerable
interface IEnumerable<'t>
static member (+) : NonEmptyList<'a1> * x: NonEmptyList<'a1> -> NonEmptyList<'a1>
static member (<*>) : f: NonEmptyList<('T -> 'U)> * x: NonEmptyList<'T> -> NonEmptyList<'U>
static member (<.>) : f: NonEmptyList<('T -> 'U)> * x: NonEmptyList<'T> -> NonEmptyList<'U>
static member (=>>) : s: NonEmptyList<'a1> * g: (NonEmptyList<'a1> -> 'b) -> NonEmptyList<'b>
static member (>>=) : NonEmptyList<'a1> * f: ('a1 -> NonEmptyList<'b>) -> NonEmptyList<'b>
...
<summary>
A type-safe list that contains at least one element.
</summary>
val some14: int option
union case Option.Some: Value: 'T -> Option<'T>
val tryParse: value: string -> 'T option (requires member TryParse)
<summary>
Converts to a value from its string representation. Returns None if the convertion doesn't succeed.
</summary>
<category index="21">Converter</category>
namespace System
val getLine: Async<string>
val async: AsyncBuilder
type Console =
static member Beep: unit -> unit + 1 overload
static member Clear: unit -> unit
static member GetCursorPosition: unit -> struct (int * int)
static member MoveBufferArea: sourceLeft: int * sourceTop: int * sourceWidth: int * sourceHeight: int * targetLeft: int * targetTop: int -> unit + 1 overload
static member OpenStandardError: unit -> Stream + 1 overload
static member OpenStandardInput: unit -> Stream + 1 overload
static member OpenStandardOutput: unit -> Stream + 1 overload
static member Read: unit -> int
static member ReadKey: unit -> ConsoleKeyInfo + 1 overload
static member ReadLine: unit -> string
...
<summary>Represents the standard input, output, and error streams for console applications. This class cannot be inherited.</summary>
Console.ReadLine() : string
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 =
interface IEnumerable<char>
interface IEnumerable
interface ICloneable
interface IComparable
interface IComparable<string>
interface IConvertible
interface IEquatable<string>
new: value: nativeptr<char> -> unit + 8 overloads
member Clone: unit -> obj
member CompareTo: value: obj -> int + 1 overload
...
<summary>Represents text as a sequence of UTF-16 code units.</summary>
--------------------
String(value: nativeptr<char>) : String
String(value: char array) : String
String(value: ReadOnlySpan<char>) : String
String(value: nativeptr<sbyte>) : String
String(c: char, count: int) : String
String(value: nativeptr<char>, startIndex: int, length: int) : String
String(value: char array, 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
[<Struct>]
type Char =
member CompareTo: value: char -> int + 1 overload
member Equals: obj: char -> bool + 1 overload
member GetHashCode: unit -> int
member GetTypeCode: unit -> TypeCode
member ToString: unit -> string + 2 overloads
static member ConvertFromUtf32: utf32: int -> string
static member ConvertToUtf32: highSurrogate: char * lowSurrogate: char -> int + 1 overload
static member GetNumericValue: c: char -> float + 1 overload
static member GetUnicodeCategory: c: char -> UnicodeCategory + 1 overload
static member IsAscii: c: char -> bool
...
<summary>Represents a character as a UTF-16 code unit.</summary>
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
val getValidPassword: ResultT<Async<Result<string,string>>>
Multiple items
union case ResultT.ResultT: 'monad<Result<'t,'e>> -> ResultT<'monad<Result<'t,'e>>>
--------------------
module ResultT
from FSharpPlus.Data
<summary>
Basic operations on ResultT
</summary>
--------------------
[<Struct>]
type ResultT<'monad<Result<'t,'e>>> =
| ResultT of 'monad<Result<'t,'e>>
static member (+) : ResultT<'a1> * ResultT<'a5> -> ResultT<'MonadPlus<Result<'U,'E>>> (requires member (>>=) and member (>>=) and member Return and member ``+`` and member ``+``)
static member (<*>) : f: ResultT<'Monad<Result<('T -> 'U),'E>>> * x: ResultT<'Monad<Result<'T,'E>>> -> ResultT<'Monad<Result<'U,'E>>> (requires member Map and member ``<*>``)
static member (<|>) : ResultT<'a1> * ResultT<'a5> -> ResultT<'MonadPlus<Result<'U,'E>>> (requires member (>>=) and member Return and member (>>=) and member ``+``)
static member (>=>) : f: ('T -> ResultT<'Monad<Result<'U, 'E>>) * g: ('U -> ResultT<'Monad<Result<'V, 'E>>) -> ('T -> ResultT<'Monad<Result<'V, 'E>>) (requires member (>>=) and member Return)
static member (>>=) : x: ResultT<'Monad<Result<'T,'E>>> * f: ('T -> ResultT<'Monad<Result<'U,'E>>>) -> ResultT<'Monad<Result<'U,'E>>> (requires member (>>=) and member Return)
static member CallCC: f: (('T -> ResultT<'MonadCont<'R,Result<'U,'E>>>) -> ResultT<'MonadCont<'R, Result<'T,'E>>>) -> ResultT<'MonadCont<'R, Result<'T,'E>>> (requires member CallCC)
static member Catch: ResultT<'Monad<Result<'T, 'E1>>> * 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<'Monad<Result<'T,'E>>> (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)
...
<summary>
Monad Transformer for Result<'T, 'E>
</summary>
val liftAsync: x: Async<'T> -> 'MonadAsync<'T> (requires member LiftAsync)
<summary>
A specialized lift for Async<'T> which is able to bring an Async value from any depth of monad-layers.
</summary>
<category index="18">Monad Transformers</category>
val throw: error: 'E -> ''MonadError<'E,'T> (requires member Throw)
<summary>
Throws an error value inside the Error monad.
</summary>
<category index="18">Monad Transformers</category>
val catch<''MonadError<'E1,'T>,''MonadError<'E2,'T>,'E1 (requires member Catch)> : value: ''MonadError<'E1,'T> -> handler: ('E1 -> ''MonadError<'E2,'T>) -> ''MonadError<'E2,'T> (requires member Catch)
<summary>
Executes a handler when the value contained in the Error monad represents an error.
This is bindError flipped, which makes it useful when used as an operator.
</summary>
<example><code>
let doSomeOperation x = ResultT <| async {
if x < 10 then return Ok 10
else return Error "failure" }
doSomeOperation </catch/> (fun s -> throw ("The error was: " + s))
</code></example>
<category index="18">Monad Transformers</category>
val s: int
val askPassword: ResultT<Async<Result<string,string>>>
val lift: x: 'Monad<'T> -> 'MonadTrans<'Monad<'T>> (requires member Lift)
<summary>
Lifts a computation from the inner monad to the constructed monad.
</summary>
<category index="18">Monad Transformers</category>
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
<summary>
Basic operations on Writer
</summary>
--------------------
[<Struct>]
type Writer<'monoid,'t> =
| Writer of ('t * 'monoid)
static member ( *> ) : x: Writer<'Monoid,'T> * y: Writer<'Monoid,'U> -> Writer<'Monoid,'U> (requires member ``+``)
static member (<!>) : f: ('T -> 'U) * x: Writer<'Monoid,'T> -> Writer<'Monoid,'U>
static member ( <* ) : x: Writer<'Monoid,'U> * y: Writer<'Monoid,'T> -> Writer<'Monoid,'U> (requires member ``+``)
static member (<*>) : f: Writer<'Monoid,('T -> 'U)> * x: Writer<'Monoid,'T> -> Writer<'Monoid,'U> (requires member ``+``)
static member (=>>) : g: Writer<'T,'W> * f: (Writer<'T,'W> -> 'U) -> Writer<'U,'W>
static member (>=>) : f: ('T -> Writer<'Monoid,'U>) * g: ('U -> Writer<'Monoid,'V>) -> ('T -> Writer<'Monoid,'V>) (requires member ``+``)
static member (>>=) : x: Writer<'Monoid,'T> * f: ('T -> Writer<'Monoid,'U>) -> Writer<'Monoid,'U> (requires member ``+``)
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>
...
<summary> Computation type: Computations which produce a stream of data in addition to the computed values.
<para /> Binding strategy: Combines the outputs of the subcomputations using <c>mappend</c>.
<para /> Useful for: Logging, or other computations that produce output "on the side". </summary>
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: ResultT<'Monad<Result<'T,'E>>> -> 'Monad<Result<'T,'E>>
val run: Writer<'Monoid,'T> -> 'T * 'Monoid
<summary>
Unwraps a writer computation as a (result, output) pair. (The inverse of Writer.)
</summary>
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
<summary>
Additional operations on Result
</summary>
--------------------
module Result
from FSharpPlus
<summary>
Additional operations on Result<'T,'Error>
</summary>
--------------------
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
union case ReaderT.ReaderT: ('r -> 'monad<'t>) -> ReaderT<'r,'monad<'t>>
--------------------
module ReaderT
from FSharpPlus.Data
<summary>
Basic operations on Reader
</summary>
--------------------
[<Struct>]
type ReaderT<'r,'monad<'t>> =
| ReaderT of ('r -> 'monad<'t>)
static member ( *> ) : x: ReaderT<'R,'Monad<'T>> * y: ReaderT<'R,'Monad<'U>> -> ReaderT<'R,'Monad<'U>> (requires member Map and member ``<*>``)
static member (<!>) : f: ('T -> 'U) * x: ReaderT<'R,'Monad<'T>> -> ReaderT<'R,'Monad<'U>> (requires member Map)
static member ( <* ) : x: ReaderT<'R,'Monad<'U>> * y: ReaderT<'R,'Monad<'T>> -> ReaderT<'R,'Monad<'U>> (requires member Map and member ``<*>``)
static member (<*>) : f: ReaderT<'R,'Monad<'T -> 'U>> * x: ReaderT<'R,'Monad<'T>> -> ReaderT<'R,'Monad<'U>> (requires member ``<*>``)
static member (<|>) : ReaderT<'R,'MonadPlus<'T>> * ReaderT<'R,'MonadPlus<'T>> -> ReaderT<'R,'MonadPlus<'T>> (requires member ``<|>``)
static member (>=>) : f: ('T -> Reader<'R,'U>) * g: ('U -> Reader<'R,'V>) -> ('T -> Reader<'R,'V>) + 1 overload
static member (>>=)<'R,'Monad<'T>,'Monad<'U>,'T (requires member (>>=))> : x: ReaderT<'R,'Monad<'T>> * f: ('T -> ReaderT<'R,'Monad<'U>>) -> ReaderT<'R,'Monad<'U>> (requires member (>>=))
static member CallCC: f: (('T -> ReaderT<'R,'MonadCont<'C,'U>>) -> ReaderT<'R,'MonadCont<'C,'T>>) -> ReaderT<'R,'MonadCont<'C,'T>> (requires member CallCC)
static member Catch<'R,'MonadError<'E1,'T>,'MonadError<'E2,'T>,'E1 (requires member Catch)> : m: ReaderT<'R,'MonadError<'E1,'T>> * h: ('E1 -> ReaderT<'R,'MonadError<'E2,'T>>) -> ReaderT<'R,'MonadError<'E2,'T>> (requires member Catch)
static member Delay: body: (unit -> ReaderT<'R,'Monad<'T>>) -> ReaderT<'R,'Monad<'T>> (requires member Delay)
...
<summary>
Monad Transformer for Reader<'R, 'T>
</summary>
val now: DateTime
Multiple items
[<Struct>]
type DateTime =
new: year: int * month: int * day: int -> unit + 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
...
<summary>Represents an instant in time, typically expressed as a date and time of day.</summary>
--------------------
DateTime ()
(+0 other overloads)
DateTime(ticks: int64) : DateTime
(+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : DateTime
(+0 other overloads)
val a: 'b
DateTime.ToString() : string
DateTime.ToString(format: string) : string
DateTime.ToString(provider: IFormatProvider) : string
DateTime.ToString(format: string, provider: IFormatProvider) : string
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)
val expr: ReaderT<'a,ResultT<Writer<'b,'c>>>
val run: ReaderT<'R,'Monad<'T>> -> ('R -> 'Monad<'T>)
property DateTime.UtcNow: DateTime with get
<summary>Gets a <see cref="T:System.DateTime" /> object that is set to the current date and time on this computer, expressed as the Coordinated Universal Time (UTC).</summary>
<returns>An object whose value is the current UTC date and time.</returns>
module Suave
from Abstraction-monad
type WebPart<'a> = 'a -> OptionT<Async<'a option>>
'a
Multiple items
union case OptionT.OptionT: 'monad<option<'t>> -> OptionT<'monad<option<'t>>>
--------------------
module OptionT
from FSharpPlus.Data
<summary>
Basic operations on OptionT
</summary>
--------------------
[<Struct>]
type OptionT<'monad<option<'t>>> =
| OptionT of 'monad<option<'t>>
static member (+) : OptionT<'a1> * OptionT<'MonadPlus<option<'T>> -> OptionT<'MonadPlus<option<'T>> (requires member (>>=) and member (>>=) and member Return and member ``+``)
static member (<*>) : f: OptionT<'Monad<option<('T -> 'U)>> * x: OptionT<'Monad<option<'T>> -> OptionT<'Monad<option<'U>> (requires member Map and member ``<*>``)
static member (<|>) : OptionT<'a1> * OptionT<'MonadPlus<option<'T>> -> OptionT<'MonadPlus<option<'T>> (requires member (>>=) and member Return)
static member (>=>) : f: ('T -> OptionT<'Monad<option<'U>>) * g: ('U -> OptionT<'Monad<option<'V>>) -> ('T -> OptionT<'Monad<option<'V>>) (requires member (>>=) and member Return)
static member (>>=) : x: OptionT<'Monad<option<'T>> * f: ('T -> OptionT<'Monad<option<'U>>) -> OptionT<'Monad<option<'U>> (requires member (>>=) and member Return)
static member CallCC: f: (('T -> OptionT<'MonadCont<'R,option<'U>>>) -> OptionT<'MonadCont<'R,option<'T>>>) -> OptionT<'MonadCont<'R,option<'T>>> (requires member CallCC)
static member Catch<'MonadError<'E1,'T>,'MonadError<'E2,'T>,'E1 (requires member Catch)> : m: OptionT<'MonadError<'E1,'T>> * h: ('E1 -> OptionT<'MonadError<'E2,'T>>) -> OptionT<'MonadError<'E2,'T>> (requires member Catch)
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)
...
<summary>
Monad Transformer for Option<'T>
</summary>
Multiple items
module Async
from FSharpPlus
<summary>
Additional operations on Async
</summary>
--------------------
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 AwaitTask: task: Task<'T> -> Async<'T> + 1 overload
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: Async<'T option> seq -> Async<'T option>
static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads
static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
...
--------------------
type Async<'T>
Multiple items
val option: f: ('g -> 'h) -> n: 'h -> _arg1: 'g option -> 'h
<summary>
Takes a function, a default value and a option value. If the option value is None, the function returns the default value.
Otherwise, it applies the function to the value inside Some and returns the result.
</summary>
<category index="0">Common Combinators</category>
--------------------
type 'T option = Option<'T>
val succeed: x: 'a -> Async<'a option>
val x: 'a
member AsyncBuilder.Return: value: 'T -> Async<'T>
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 =
interface ISerializable
new: uriString: string -> unit + 6 overloads
member Equals: comparand: obj -> bool
member GetComponents: components: UriComponents * format: UriFormat -> string
member GetHashCode: unit -> int
member GetLeftPart: part: UriPartial -> string
member IsBaseOf: uri: Uri -> bool
member IsWellFormedOriginalString: unit -> bool
member MakeRelative: toUri: Uri -> string
member MakeRelativeUri: uri: Uri -> Uri
...
<summary>Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the URI.</summary>
--------------------
Uri(uriString: string) : Uri
Uri(uriString: string, creationOptions: inref<UriCreationOptions>) : 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
from Abstraction-monad.Suave
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>>)
property Uri.AbsolutePath: string with get
<summary>Gets the absolute path of the URI.</summary>
<exception cref="T:System.InvalidOperationException">This instance represents a relative URI, and this property is valid only for absolute URIs.</exception>
<returns>The absolute path to the resource.</returns>
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
from Abstraction-monad.Suave
module Filters
from Abstraction-monad.Suave
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
type 'T list = List<'T>
NoteList.offset: int
NoteList.chunk: int
NoteList.total: int
type IDb =
abstract addUserNote: int -> string -> Async<Note>
abstract getUserNotes: int -> Async<NoteList>
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
abstract IDb.getUserNotes: int -> Async<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>>
Http.HttpContext.request: Http.HttpRequest
module Request
from Abstraction-monad.Suave
val text: string
val newNote: Note
abstract IDb.addUserNote: int -> string -> Async<Note>
val rvm: string
val msg: string
val BAD_REQUEST: s: string -> (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)
val choice: x: 'Foldable<'Alternative<'T>> -> 'Alternative<'T>> (requires member Choice)
<summary>
Reduces using alternative operator `<|>`.
</summary>
<category index="23">Additional Functions</category>
val path: s: string -> (Http.HttpContext -> OptionT<Async<Http.HttpContext option>>)