Applicative Functors which also have a monoid structure.
___
return x
/ result x
(<*>) f x
empty
append x y
/ (<|>) x y
static member Return (x: 'T) : 'Alternative<'T>
static member (<*>) (f: 'T -> 'U, x: 'Alternative<'T>) : 'Alternative<'U>
static member get_Empty () : 'Alternative
static member (<|>) (x: 'Alternative<'T>, y: 'Alternative<'T>) : 'Alternative<'T>
Note: return
can't be used outside computation expressions, use result
instead.
static member MFilter (x: seq<'Alternative>) : 'Alternative
static member inline Choice (source: 'Foldable<'Alt<'T>>) : 'Alt<'T>
empty <|> x = x
x <|> empty = x
(x <|> y) <|> z = x <|> (y <|> z)
f <!> (x <|> y) = (f <!> x) <|> (f <!> y)
(f <|> g) <*> x = (f <*> x) <|> (g <*> x)
empty <*> f = empty
Monoid: An Alternative is a Monoid that is also an Applicative Functor
Applicative: An Alternative is a Monoid that is also an Applicative Functor
-
MonadPlus: Alternatives that are also Monads
From .Net/F#
list<'T>
array<'T>
seq<'T>
option<'T>
voption<'T>
Result<'T, 'Monoid>
Choice<'T, 'Monoid>
'T -> 'Alternative
From F#+
*
Only <|>
operation
Suggest another concrete implementation
open FSharpPlus
// this gives [2; 3; 4; 5]
let x = [2;3] <|> [] <|> [4;5]
// but I could have written
let y = [2;3] <|> empty <|> [4;5]
// choice sample usage
let alternatives = [None; Some "Result is OK"; None ; Some "Result is still OK"]
let firstGood = choice alternatives //Some "Result is OK"
// it did something like
let fstGood = None <|> Some "Result is OK" <|> None <|> Some "Result is still OK"
// mfilter usage
let fstMatch = mfilter ((=) 5) [1;2;3;4] // [] -> no element found, it uses the empty value
// MonadPlus
let getLine = async { return System.Console.ReadLine() }
let putStrLn x = async { printfn "%s" x}
let nameAndAddress = traverse (fun x -> putStrLn x >>= fun _ -> getLine) ["name";"address"]
let a:list<int> = empty
let res123 = empty <|> [1;2;3]
let inline mfilter p ma = monad.plus {
let! a = ma
if p a then return a else return! empty}
let mfilterRes2 = mfilter ((=)2) (Some 2)
// sample code from http://en.wikibooks.org/wiki/Haskell/MonadPlus
let pythags = monad {
let! z = [1..50]
let! x = [1..z]
let! y = [x..z]
do! guard (x*x + y*y = z*z)
return (x, y, z)}
// same operation but using the monad.plus computation expression
let pythags' = monad.plus {
let! z = [1..50]
let! x = [1..z]
let! y = [x..z]
if (x*x + y*y = z*z) then return (x, y, z) else ()}
let allCombinations = sequence [['a'; 'b'; 'c']; ['1'; '2']]
// An Alternative is automatically a Monoid and a Functor
type Maybe<'t> =
| Just of 't
| Nothing
with
static member Return (x:'a) = Just x
static member (<*>) (f, x) =
match (f, x) with
| Just f, Just x -> Just (f x)
| _ -> Nothing
static member inline get_Empty () = Nothing
static member inline (<|>) (x, y) = match x with Nothing -> y | xs -> xs
let r5 = Nothing ++ Just 5 ++ Just 6 ++ zero
let r6 = map string (Just 6)
// But not always the Monoidal behaviour is the same
let r3 = Some 2 ++ Some 1 // addition => Some 3
let r2 = Some 2 <|> Some 1 // first success => Some 2
Multiple items
val seq: sequence: 'T seq -> 'T seq
--------------------
type 'T seq = System.Collections.Generic.IEnumerable<'T>
Multiple items
type Choice<'T1,'T2> =
| Choice1Of2 of 'T1
| Choice2Of2 of 'T2
--------------------
type Choice<'T1,'T2,'T3> =
| Choice1Of3 of 'T1
| Choice2Of3 of 'T2
| Choice3Of3 of 'T3
--------------------
type Choice<'T1,'T2,'T3,'T4> =
| Choice1Of4 of 'T1
| Choice2Of4 of 'T2
| Choice3Of4 of 'T3
| Choice4Of4 of 'T4
--------------------
type Choice<'T1,'T2,'T3,'T4,'T5> =
| Choice1Of5 of 'T1
| Choice2Of5 of 'T2
| Choice3Of5 of 'T3
| Choice4Of5 of 'T4
| Choice5Of5 of 'T5
--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6> =
| Choice1Of6 of 'T1
| Choice2Of6 of 'T2
| Choice3Of6 of 'T3
| Choice4Of6 of 'T4
| Choice5Of6 of 'T5
| Choice6Of6 of 'T6
--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6,'T7> =
| Choice1Of7 of 'T1
| Choice2Of7 of 'T2
| Choice3Of7 of 'T3
| Choice4Of7 of 'T4
| Choice5Of7 of 'T5
| Choice6Of7 of 'T6
| Choice7Of7 of 'T7
namespace FSharpPlus
val x: int list
val y: int list
val empty<'Functor<'T> (requires member Empty)> : 'Functor<'T> (requires member Empty)
<summary>
A functor representing the empty value.
</summary>
<category index="5">Alternative/Monadplus/Arrowplus</category>
val alternatives: string option list
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val firstGood: string 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 fstGood: string option
val fstMatch: int list
val mfilter: predicate: ('T -> bool) -> m: 'MonadZero<'T> -> 'MonadZero<'T> (requires member (>>=) and member Return and member Empty)
<summary>
Generic filter operation for MonadZero. It returns all values satisfying the predicate, if the predicate returns false will use the empty value.
</summary>
<category index="23">Additional Functions</category>
val getLine: Async<string>
val async: AsyncBuilder
namespace System
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>
System.Console.ReadLine() : string
val putStrLn: x: string -> Async<unit>
val x: string
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
val nameAndAddress: Async<string list>
val traverse: f: ('T -> 'Functor<'U>) -> t: 'Traversable<'T> -> 'Functor<'Traversable<'U>> (requires member Traverse)
<summary>
Map each element of a structure to an action, evaluate these actions from left to right, and collect the results.
</summary>
<category index="13">Traversable</category>
val a: int list
type 'T list = List<'T>
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> =
int
val res123: int list
val mfilter: p: ('a -> bool) -> ma: 'b -> 'c (requires member (>>=) and member Empty and member Return and member Delay)
val p: ('a -> bool)
val ma: 'b (requires member (>>=) and member Empty and member Return and member Delay)
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 a: 'a
val mfilterRes2: int option
val pythags: (int * int * int) list
val z: int
val x: int
val y: int
val guard: x: bool -> 'MonadPlus<unit> (requires member Return and member Empty)
<summary>
Conditional failure of Alternative computations.
If true it lifts the unit value, else it returns empty.
Common uses of guard include conditionally signaling an error in an error monad and conditionally rejecting the current choice in an Alternative-based parser.
</summary>
<category index="5">Alternative/Monadplus/Arrowplus</category>
val pythags': (int * int * int) list
val allCombinations: char list list
val sequence: t: 'Traversable<'Functor<'T>> -> 'Functor<'Traversable<'T>> (requires member Sequence)
<summary>
Evaluate each action in the structure from left to right, and collect the results.
</summary>
<category index="13">Traversable</category>
't
union case Maybe.Just: 't -> Maybe<'t>
union case Maybe.Nothing: Maybe<'t>
val x: 'a
'a
val f: Maybe<('a -> 'b)>
val x: Maybe<'a>
val f: ('a -> 'b)
val y: Maybe<'a>
val xs: Maybe<'a>
val r5: Maybe<int>
val zero<'Monoid (requires member Zero)> : 'Monoid (requires member Zero)
<summary>
A value that represents the 0 element of a Monoid.
</summary>
<category index="4">Monoid</category>
val r6: Maybe<string>
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>
Multiple items
val string: value: 'T -> string
--------------------
type string = System.String
val r3: int option
val r2: int option