A functor with application, providing operations to embed pure expressions (return
), and sequence computations and combine their results (<*>
).
___
return x
/result x
(<*>) f x
static member Return (x:'T) : 'Applicative<'T>
static member (<*>) (f: 'Applicative<'T->'U>, x: 'Applicative<'T>) : 'Applicative<'U>
Note: return
can't be used outside computation expressions, use result
instead.
static member Lift2 (f: 'T1->'T2->'T, x1: 'Applicative<'T1>, x2: 'Applicative<'T2>) : 'Applicative<'T>
result id <*> v = v
result (<<) <*> u <*> v <*> w = u <*> (v <*> w)
result f <*> result x = result (f x)
u <*> result y = result ((|>) y) <*> u
Functor: An applicative is a functor whose map
operation can be splitted in return
and (<*>)
operations,
-
Monad : Monads are functors with an additional Join
operation,
From F#
seq<'T>
list<'T>
array<'T>
'T [,]
'T [,,]
'T [,,,]
option<'T>
IObservable<'T>
Lazy<'T>
Async<'T>
Result<'T,'U>
Choice<'T,'U>
KeyValuePair<'Key,'T>
'Monoid * 'T
Task<'T>
'R->'T
Expr<'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>>
SeqT<'Monad<seq<'T>>
ListT<'Monad<list<'T>>
ResultT<'Monad<Result<'T,'TError>>
ChoiceT<'Monad<Choice<'T,'TError>>
Free<'Functor<'T>,'T>
NonEmptyList<'T>
Validation<'Error,'T>
ZipList<'T>
ParallelArray<'T>
Const<'C,'T>
Compose<'ApplicativeF<'ApplicativeG<'T>>>
DList<'T>
Vector<'T,'Dimension>
Matrix<'T,'Rows,'Columns>
Restricted:
- string
- StringBuilder
- Set<'T>
- IEnumerator<'T>
Suggest another concrete implementation
open FSharpPlus
open FSharpPlus.Data
// Apply +4 to a list
let lst5n6 = map ((+) 4) [ 1;2 ]
// Apply +4 to an array
let arr5n6 = map ((+) 4) [|1;2|]
// I could have written this
let arr5n6' = (+) <!> [|4|] <*> [|1;2|]
// Add two options
let opt120 = (+) <!> Some 20 <*> tryParse "100"
// Applicatives need Return (result)
// Test return
let resSome22 : option<_> = result 22
let resSing22 : list<_> = result 22
let resLazy22 : Lazy<_> = result 22
let (quot5 : Microsoft.FSharp.Quotations.Expr<int>) = result 5
// Example
type Person = { name: string; age: int } with static member create n a = {name = n; age = a}
let person1 = Person.create <!> tryHead ["gus"] <*> tryParse "42"
let person2 = Person.create <!> tryHead ["gus"] <*> tryParse "fourty two"
let person3 = Person.create <!> tryHead ["gus"] <*> (tryHead ["42"] >>= tryParse)
// Other ways to write applicative expressions
// Function lift2 helps in many cases
let person1' = (tryHead ["gus"], tryParse "42") ||> lift2 Person.create
let person2' = (tryHead ["gus"], tryParse "fourty two") ||> lift2 Person.create
let person3' = (tryHead ["gus"], tryHead ["42"] >>= tryParse) ||> lift2 Person.create
// Using Idiom brackets from http://www.haskell.org/haskellwiki/Idiom_brackets
let res3n4 = iI ((+) 2) [1;2] Ii
let res3n4' = iI (+) (result 2) [1;2] Ii
let res18n24 = iI (+) (ZipList(seq [8;4])) (ZipList(seq [10;20])) Ii
let tryDiv x y = if y = 0 then None else Some (x </div/> y)
let resSome3 = join (iI tryDiv (Some 6) (Some 2) Ii)
let resSome3' = iI tryDiv (Some 6) (Some 2) Ji
let tryDivBy y = if y = 0 then None else Some (fun x -> x </div/> y)
let resSome2 = join (result tryDivBy <*> Some 4) <*> Some 8
let resSome2' = join ( iI tryDivBy (Some 4) Ii) <*> Some 8
let resSome2'' = iI tryDivBy (Some 4) J (Some 8) Ii
let resNone = iI tryDivBy (Some 0) J (Some 8) Ii
let res16n17 = iI (+) (iI (+) (result 4) [2; 3] Ii) [10] Ii
let opt121 = iI (+) (Some 21) (tryParse "100") Ii
let opt122 = iI tryDiv (tryParse "488") (trySqrt 16) Ji
// Using applicative math operators
open FSharpPlus.Math.Applicative
let opt121' = Some 21 .+. tryParse "100"
let optTrue = 30 >. tryParse "29"
let optFalse = tryParse "30" .< 29
let m1m2m3 = -.[1;2;3]
// Composing applicatives
let res4 = (+) <!> Compose [Some 3] <*> Compose [Some 1]
let getName s = async { return tryHead s }
let getAge s = async { return tryParse s }
let person4 = Person.create <!> Compose (getName ["gus"]) <*> Compose (getAge "42")
// A Monad is automatically an Applicative
type MyList<'s> = MyList of 's seq with
static member Return (x:'a) = MyList (Seq.singleton x)
static member (>>=) (MyList x: MyList<'T>, f) = MyList (Seq.collect (f >> (fun (MyList x) -> x)) x)
let mappedMyList : MyList<_> = (MyList [(+) 1;(+) 2;(+) 3]) <*> (MyList [1;2;3])
val id: x: 'T -> 'T
<summary>The identity function</summary>
<param name="x">The input value.</param>
<returns>The same value.</returns>
<example id="id-example"><code lang="fsharp">
id 12 // Evaulates to 12
id "abc" // Evaulates to "abc"
</code></example>
namespace FSharpPlus
namespace FSharpPlus.Data
val lst5n6: int list
val map: f: ('T -> 'U) -> x: 'Functor<'T> -> 'Functor<'U> (requires member Map)
<summary>Lifts a function into a Functor.</summary>
<category index="1">Functor</category>
val arr5n6: int[]
val arr5n6': int[]
val opt120: int option
union case Option.Some: Value: 'T -> Option<'T>
<summary>The representation of "Value of type 'T"</summary>
<param name="Value">The input value.</param>
<returns>An option representing the value.</returns>
val tryParse: value: string -> 'a 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>
val resSome22: int option
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>
<summary>The type of optional values. When used from other CLI languages the
empty option is the <c>null</c> value. </summary>
<remarks>Use the constructors <c>Some</c> and <c>None</c> to create values of this type.
Use the values in the <c>Option</c> module to manipulate values of this type,
or pattern match against the values directly.
'None' values will appear as the value <c>null</c> to other CLI languages.
Instance methods on this type will appear as static methods to other CLI languages
due to the use of <c>null</c> as a value representation.</remarks>
<category index="3">Options</category>
val result: x: 'T -> 'Functor<'T> (requires member Return)
<summary>
Lifts a value into a Functor. Same as return in Computation Expressions.
</summary>
<category index="2">Applicative</category>
val resSing22: int list
type 'T list = List<'T>
<summary>The type of immutable singly-linked lists. </summary>
<remarks>See the <see cref="T:Microsoft.FSharp.Collections.ListModule" /> module for further operations related to lists.
Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or
the notation <c>[1; 2; 3]</c>. Use the values in the <c>List</c> module to manipulate
values of this type, or pattern match against the values directly.
See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/lists">F# Language Guide - Lists</a>.
</remarks>
val resLazy22: Lazy<int>
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T
<summary>An active pattern to force the execution of values of type <c>Lazy<_></c>.</summary>
<example id="lazy-1"><code lang="fsharp">
let f (Lazy v) = v + v
let v = lazy (printf "eval!"; 5+5)
f v
f v
</code>
Evaluates to <c>10</c>. The text <c>eval!</c> is printed once on the first invocation of <c>f</c>.
</example>
--------------------
module Lazy
from FSharpPlus
<summary>
Additional operations on Lazy - delayed computations
</summary>
--------------------
type Lazy<'T> = System.Lazy<'T>
<summary>The type of delayed computations.</summary>
<remarks>Use the values in the <c>Lazy</c> module to manipulate
values of this type, and the notation <c>lazy expr</c> to create values
of type <see cref="T:System.Lazy`1" />.</remarks>
<category index="3">Lazy Computation</category>
val quot5: Quotations.Expr<int>
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Quotations
Multiple items
type Expr =
override Equals: obj: obj -> bool
member GetFreeVars: unit -> seq<Var>
member Substitute: substitution: (Var -> Expr option) -> Expr
member ToString: full: bool -> string
static member AddressOf: target: Expr -> Expr
static member AddressSet: target: Expr * value: Expr -> Expr
static member Application: functionExpr: Expr * argument: Expr -> Expr
static member Applications: functionExpr: Expr * arguments: Expr list list -> Expr
static member Call: methodInfo: MethodInfo * arguments: Expr list -> Expr + 1 overload
static member CallWithWitnesses: methodInfo: MethodInfo * methodInfoWithWitnesses: MethodInfo * witnesses: Expr list * arguments: Expr list -> Expr + 1 overload
...
<summary>Quoted expressions annotated with System.Type values. </summary>
--------------------
type Expr<'T> =
inherit Expr
member Raw: Expr
<summary>Type-carrying quoted expressions. Expressions are generated either
by quotations in source text or programatically</summary>
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
<summary>Converts the argument to signed 32-bit integer. This is a direct conversion for all
primitive numeric types. For strings, the input is converted using <c>Int32.Parse()</c>
with InvariantCulture settings. Otherwise the operation requires an appropriate
static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted int</returns>
<example id="int-example"><code lang="fsharp"></code></example>
--------------------
[<Struct>]
type int = int32
<summary>An abbreviation for the CLI type <see cref="T:System.Int32" />.</summary>
<category>Basic Types</category>
--------------------
type int<'Measure> =
int
<summary>The type of 32-bit signed integer numbers, annotated with a unit of measure. The unit
of measure is erased in compiled code and when values of this type
are analyzed using reflection. The type is representationally equivalent to
<see cref="T:System.Int32" />.</summary>
<category>Basic Types with Units of Measure</category>
Person.name: string
Multiple items
val string: value: 'T -> string
<summary>Converts the argument to a string using <c>ToString</c>.</summary>
<remarks>For standard integer and floating point values the and any type that implements <c>IFormattable</c><c>ToString</c> conversion uses <c>CultureInfo.InvariantCulture</c>. </remarks>
<param name="value">The input value.</param>
<returns>The converted string.</returns>
<example id="string-example"><code lang="fsharp"></code></example>
--------------------
type string = System.String
<summary>An abbreviation for the CLI type <see cref="T:System.String" />.</summary>
<category>Basic Types</category>
Person.age: int
val n: string
val a: int
val person1: Person option
type Person =
{
name: string
age: int
}
static member create: n: string -> a: int -> Person
static member Person.create: n: string -> a: int -> Person
val tryHead: source: 'Foldable<'T> -> 'T option (requires member TryHead)
<summary>Gets the first element of the foldable, or
<c>None</c> if the foldable is empty.</summary>
<category index="11">Foldable</category>
<param name="source">The input foldable.</param>
<returns>The first element of the foldable or None.</returns>
val person2: Person option
val person3: Person option
val person1': Person option
val lift2: f: ('T -> 'U -> 'V) -> x: 'Applicative<'T> -> y: 'Applicative<'U> -> 'Applicative<'V> (requires member Lift2)
<summary>
Applies 2 lifted arguments to a non-lifted function. Equivalent to map2 in non list-like types.
</summary>
<category index="2">Applicative</category>
val person2': Person option
val person3': Person option
val res3n4: int list
val iI: x: 'a -> ('b -> 'd) (requires member ($) and member Return)
Multiple items
union case Ii.Ii: Ii
--------------------
type Ii = | Ii
val res3n4': int list
val res18n24: ZipList<int>
Multiple items
union case ZipList.ZipList: seq<'s> -> ZipList<'s>
--------------------
module ZipList
from FSharpPlus.Data
<summary>
Basic operations on ZipList
</summary>
--------------------
type ZipList<'s> =
| ZipList of seq<'s>
member Item: n: int -> 's
static member (+) : x: ZipList<'a> * y: ZipList<'a> -> ZipList<'a> (requires member ``+``)
static member (<*>) : ZipList<('a -> 'b)> * ZipList<'a> -> ZipList<'b>
static member (<|>) : ZipList<'a1> * ZipList<'a1> -> ZipList<'a1>
static member Return: x: 'a -> ZipList<'a>
static member ToSeq: ZipList<'a1> -> seq<'a1>
static member Traverse: ZipList<'T> * f: ('T -> 'Functor<'U>) -> 'Functor<ZipList<'U>> (requires member ``<*>`` and member IsLeftZero and member Map and member Return and member Map and member Traverse and member Map)
static member get_Empty: unit -> ZipList<'a1>
static member get_Zero: unit -> ZipList<'a> (requires member Zero)
<summary>
A sequence with an Applicative functor based on zipping.
</summary>
Multiple items
val seq: sequence: seq<'T> -> seq<'T>
<summary>Builds a sequence using sequence expression syntax</summary>
<param name="sequence">The input sequence.</param>
<returns>The result sequence.</returns>
<example id="seq-cast-example"><code lang="fsharp">
seq { for i in 0..10 do yield (i, i*i) }
</code></example>
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
<summary>An abbreviation for the CLI type <see cref="T:System.Collections.Generic.IEnumerable`1" /></summary>
<remarks>
See the <see cref="T:Microsoft.FSharp.Collections.SeqModule" /> module for further operations related to sequences.
See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/sequences">F# Language Guide - Sequences</a>.
</remarks>
val tryDiv: x: int -> y: int -> int option
val x: int
val y: int
union case Option.None: Option<'T>
<summary>The representation of "No value"</summary>
val div: dividend: 'Num -> divisor: 'Num -> 'Num (requires member Divide)
<summary>Division between two numbers. If the numbers are not divisible throws an error.</summary>
<category index="22">Numerics</category>
val resSome3: int option
val join: x: 'Monad<Monad<'T>> -> 'Monad<'T> (requires member Join)
<summary>
Flattens two layers of monadic information into one.
</summary>
<category index="3">Monad</category>
val resSome3': int option
Multiple items
union case Ji.Ji: Ji
--------------------
type Ji = | Ji
val tryDivBy: y: int -> (int -> int) option
val resSome2: int option
val resSome2': int option
val resSome2'': int option
union case J.J: J
val resNone: int option
val res16n17: int list
val opt121: int option
val opt122: int option
val trySqrt: x: 'a -> 'a option (requires member TrySqrt)
<summary>Square root of a number of any type. Returns None if there is no square root.</summary>
<category index="22">Numerics</category>
namespace FSharpPlus.Math
module Applicative
from FSharpPlus.Math
<summary>Math Operators ready to use over Applicative Functors.</summary>
val opt121': int option
val optTrue: bool option
val optFalse: bool option
val m1m2m3: int list
val res4: Compose<int option list>
Multiple items
union case Compose.Compose: 'functorF<'functorG<'t>> -> Compose<'functorF<'functorG<'t>>>
--------------------
module Compose
from FSharpPlus.Data
<summary>
Basic operations on Compose
</summary>
--------------------
[<Struct>]
type Compose<'functorF<'functorG<'t>>> =
| Compose of 'functorF<'functorG<'t>>
static member ( *> ) : x: 'FunctorF<'FunctorG<'T>> * y: 'FunctorF<'FunctorG<'U>> -> 'FunctorF<'FunctorG<'U>> (requires member Map and member ``<*>``)
static member (<!>) : f: ('T -> 'U) * x: 'FunctorF<'FunctorG<'T>> -> Compose<'FunctorF<'FunctorG<'U>>> (requires member Map and member Map)
static member ( <* ) : x: 'FunctorF<'FunctorG<'U>> * y: 'FunctorF<'FunctorG<'T>> -> 'FunctorF<'FunctorG<'U>> (requires member ``<*>`` and member Map)
static member (<*>) : Compose<'ApplicativeF<'ApplicativeG<'T->'U>> * Compose<'ApplicativeF<'ApplicativeG<'T>> -> Compose<'ApplicativeF<'ApplicativeG<'U>> (requires member Map and member ``<*>`` and member ``<*>``)
static member (<|>) : Compose<'AlternativeF<'ApplicativeG<'T>> * Compose<'AlternativeF<'ApplicativeG<'T>> -> Compose<'AlternativeF<'ApplicativeG<'T>> (requires member ``<|>``)
static member Lift2: f: ('T -> 'U -> 'V) * Compose<'ApplicativeF<'ApplicativeG<'T>> * Compose<'ApplicativeF<'ApplicativeG<'U>> -> Compose<'ApplicativeF<'ApplicativeG<'V>> (requires member Lift2 and member Lift2)
static member Lift3: f: ('T -> 'U -> 'V -> 'W) * Compose<'ApplicativeF<'ApplicativeG<'T>> * Compose<'ApplicativeF<'ApplicativeG<'U>> * Compose<'ApplicativeF<'ApplicativeG<'V>> -> Compose<'ApplicativeF<'ApplicativeG<'W>> (requires member Lift3 and member Lift3)
static member Map: Compose<'FunctorF<'FunctorG<'T>>> * f: ('T -> 'U) -> Compose<'FunctorF<'FunctorG<'U>>> (requires member Map and member Map)
static member Return: x: 'T -> Compose<'ApplicativeF<'ApplicativeG<'T>> (requires member Return and member Return)
static member get_Empty: unit -> Compose<'AlternativeF<'ApplicativeG<'T>> (requires member Empty)
<summary>
Right-to-left composition of functors. The composition of applicative functors is always applicative, but the composition of monads is not always a monad.
</summary>
val getName: s: string list -> Async<string option>
val s: string list
val async: AsyncBuilder
<summary>Builds an asynchronous workflow using computation expression syntax.</summary>
<example id="async-1"><code lang="fsharp">
let sleepExample() =
async {
printfn "sleeping"
do! Async.Sleep 10
printfn "waking up"
return 6
}
sleepExample() |> Async.RunSynchronously
</code></example>
val getAge: s: string -> Async<int option>
val s: string
val person4: Compose<Async<Person option>>
Multiple items
union case MyList.MyList: seq<'s> -> MyList<'s>
--------------------
type MyList<'s> =
| MyList of seq<'s>
static member (>>=) : MyList<'T> * f: ('T -> MyList<'a>) -> MyList<'a>
static member Return: x: 'a -> MyList<'a>
val x: 'a
Multiple items
module Seq
from FSharpPlus.Data
<summary>
Additional operations on Seq
</summary>
--------------------
module Seq
from FSharpPlus.Operators
--------------------
module Seq
from FSharpPlus
<summary>
Additional operations on Seq
</summary>
--------------------
module Seq
from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.seq`1" />.</summary>
val singleton: value: 'T -> seq<'T>
<summary>Returns a sequence yielding one item only.</summary>
<param name="value">The input item.</param>
<returns>The result sequence of one item.</returns>
<example id="singleton-1"><code lang="fsharp">
Seq.singleton 7
</code>
Evaluates to a sequence yielding the same results as <c>seq { 7 }</c>.
</example>
val x: seq<'T>
val f: ('T -> MyList<'a>)
val collect: mapping: ('T -> #seq<'U>) -> source: seq<'T> -> seq<'U>
<summary>Applies the given function to each element of the sequence and concatenates all the
results.</summary>
<remarks>Remember sequence is lazy, effects are delayed until it is enumerated.</remarks>
<param name="mapping">A function to transform elements of the input sequence into the sequences
that will then be concatenated.</param>
<param name="source">The input sequence.</param>
<returns>The result sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
<example id="collect-1"><code lang="fsharp">
type Foo = { Bar: int seq }
let input = seq { {Bar = [1; 2]}; {Bar = [3; 4]} }
input |> Seq.collect (fun foo -> foo.Bar)
</code>
Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4 }</c></example>
<example id="collect-2"><code lang="fsharp">
let input = [[1; 2]; [3; 4]]
input |> Seq.collect id
</code>
Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4 }</c></example>
val x: seq<'a>
val mappedMyList: MyList<int>