The Functor abstraction is used for types that can be mapped over.
___
map f x
/ (|>>) x f
/ (<<|) f x
/ (<!>) f x
static member Map (x: 'Functor<'T>, f: 'T -> 'U) : 'Functor<'U>
static member Unzip (x: 'Functor<'T * 'U>) : 'Functor<'T> * 'Functor<'U>
map id = id
map (f << g) = map f << map g
Applicative: 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>
voption<'T>
IObservable<'T>
Lazy<'T>
Async<'T>
Result<'T,'U>
Choice<'T,'U>
KeyValuePair<'Key, 'T>
Map<'Key,'T>
'Monoid * 'T
'struct ('Monoid * 'T)
Task<'T>
ValueTask<'T>
'R->'T
Expr<'T>
Dictionary<'Key, 'T>
IDictionary<'Key,' T>
IReadOnlyDictionary<'Key, 'T>
ResizeArray<'T>
From F#+
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>
NonEmptySet<'T>
NonEmptyMap<'Key, 'T>
Validation<'Error, 'T>
ZipList<'T>
ParallelArray<'T>
Const<'C, 'T>
Compose<'AlternativeF<'AlternativeG<'T>>>
DList<'T>
Kleisli<'T, 'Monad<'U>>
Coproduct<'FunctorL<'T>, 'FunctorR<'T>>
Vector<'T, 'Dimension>
Matrix<'T, 'Rows, 'Columns>
Restricted:
- string
- StringBuilder
- Set<'T>
- IEnumerator<'T>
Suggest another concrete implementation
open FSharpPlus
open FSharpPlus.Math.Generic
let getLine = async { return System.Console.ReadLine () }
let putStrLn x = async { printfn "%s" x}
let print x = async { printfn "%A" x}
// Test IO
let action = monad {
do! putStrLn "What is your first name?"
let! fn = getLine
do! putStrLn ("Thanks, " + fn)
do! putStrLn ("What is your last name?")
let! ln = getLine
let fullname = fn + " " + ln
do! putStrLn ("Your full name is: " + fullname)
return fullname }
// Test Functors
let times2,minus3 = (*) 2, (-)/> 3
let resSome1 = map minus3 (Some 4G)
let noValue = map minus3 None
let lstTimes2 = map times2 [1;2;3;4]
let fTimes2minus3 = map minus3 times2
let res39 = fTimes2minus3 21G
let getChars = map (fun (x: string) -> x.ToCharArray () |> Seq.toList) action
let quot7 = map ((+) 2) <@ 5 @>
// try -> runIO getChars ;;
// Define a type Tree
type Tree<'a> =
| Tree of 'a * Tree<'a> * Tree<'a>
| Leaf of 'a
static member map f (t:Tree<'a> ) =
match t with
| Leaf x -> Leaf (f x)
| Tree (x, t1, t2) -> Tree (f x, Tree.map f t1, Tree.map f t2)
// add instance for Functor class
static member Map (x: Tree<_>, f) = Tree.map f x
let myTree = Tree(6, Tree(2, Leaf 1, Leaf 3), Leaf 9)
let mappedTree = map fTimes2minus3 myTree
// An Applicative is automatically a Functor
type ZipList<'s> = ZipList of 's seq with
static member Return (x: 'a) = ZipList (Seq.initInfinite (konst x))
static member (<*>) (ZipList (f :seq<'a->'b>), ZipList x) = ZipList (Seq.zip f x |> Seq.map (fun (f, x) -> f x)) : ZipList<'b>
let mappedZipList = map string (ZipList [1; 2; 3])
// A Monad is automatically a Functor
type MyList<'s> = MyList of 's seq with
static member Return (x:'a) = MyList x
static member (>>=) (MyList x: MyList<'T>, f) = MyList (Seq.collect (f >> (fun (MyList x) -> x)) x)
let mappedMyList = map string (MyList [1; 2; 3])
-
Highly recommended Matt Thornton's blog Grokking Functors.
It contains examples using F#+ and an explanation from scratch.
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IReadOnlyDictionary<'Key,'Value>
interface IReadOnlyCollection<KeyValuePair<'Key,'Value>>
interface IEnumerable
interface IStructuralEquatable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new: elements: ('Key * 'Value) seq -> Map<'Key,'Value>
member Add: key: 'Key * value: 'Value -> Map<'Key,'Value>
...
--------------------
new: elements: ('Key * 'Value) seq -> Map<'Key,'Value>
val id: x: 'T -> 'T
namespace FSharpPlus
namespace FSharpPlus.Math
module Generic
from FSharpPlus.Math
<summary>
Generic numbers, functions and operators.
By opening this module some common operators become restricted, like (+) to 'T->'T->'T
</summary>
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 print: x: 'a -> Async<unit>
val x: 'a
val action: Async<string>
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 fn: string
val ln: string
val fullname: string
val times2: (int -> int)
val minus3: (int -> int)
val resSome1: int option
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>
union case Option.Some: Value: 'T -> Option<'T>
val noValue: int option
union case Option.None: Option<'T>
val lstTimes2: int list
val fTimes2minus3: (int -> int)
val res39: int
val getChars: Async<char list>
Multiple items
val string: value: 'T -> string
--------------------
type string = System.String
System.String.ToCharArray() : char array
System.String.ToCharArray(startIndex: int, length: int) : char array
Multiple items
module Seq
from FSharpPlus.Operators
--------------------
module Seq
from FSharpPlus
<summary>
Additional operations on Seq
</summary>
--------------------
module Seq
from Microsoft.FSharp.Collections
val toList: source: 'T seq -> 'T list
val quot7: Quotations.Expr<int>
'a
Multiple items
union case Tree.Tree: 'a * Tree<'a> * Tree<'a> -> Tree<'a>
--------------------
type Tree<'a> =
| Tree of 'a * Tree<'a> * Tree<'a>
| Leaf of 'a
static member Map<'a,'b> : x: Tree<'a0> * f: ('a0 -> 'b) -> Tree<'b>
static member map<'a> : f: ('a -> 'a0) -> t: Tree<'a> -> Tree<'a0>
union case Tree.Leaf: 'a -> Tree<'a>
val f: ('a -> 'a0)
val t: Tree<'a>
val t1: Tree<'a>
val t2: Tree<'a>
static member Tree.map<'a> : f: ('a -> 'a0) -> t: Tree<'a> -> Tree<'a0>
Multiple items
module Map
from FSharpPlus
<summary>
Additional operations on Map<'Key, 'Value>
</summary>
--------------------
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IReadOnlyDictionary<'Key,'Value>
interface IReadOnlyCollection<KeyValuePair<'Key,'Value>>
interface IEnumerable
interface IStructuralEquatable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new: elements: ('Key * 'Value) seq -> Map<'Key,'Value>
member Add: key: 'Key * value: 'Value -> Map<'Key,'Value>
...
--------------------
new: elements: ('Key * 'Value) seq -> Map<'Key,'Value>
val x: Tree<'a>
val f: ('a -> 'b)
val myTree: Tree<int>
val mappedTree: Tree<int>
's
Multiple items
union case ZipList.ZipList: 's seq -> ZipList<'s>
--------------------
type ZipList<'s> =
| ZipList of 's seq
static member (<*>) : ZipList<('a -> 'b)> * ZipList<'a> -> ZipList<'b>
static member Return: x: 'a -> ZipList<'a>
Multiple items
val seq: sequence: 'T seq -> 'T seq
--------------------
type 'T seq = System.Collections.Generic.IEnumerable<'T>
val initInfinite: initializer: (int -> 'T) -> 'T seq
val konst: k: 'T -> 'Ignored -> 'T
<summary> Creates a constant function.</summary>
<param name="k">The constant value.</param>
<returns>The constant value function.</returns>
<category index="0">Common Combinators</category>
val f: ('a -> 'b) seq
'b
val x: 'a seq
val zip: source1: 'T1 seq -> source2: 'T2 seq -> ('T1 * 'T2) seq
val map: mapping: ('T -> 'U) -> source: 'T seq -> 'U seq
val mappedZipList: ZipList<string>
Multiple items
union case MyList.MyList: 's seq -> MyList<'s>
--------------------
type MyList<'s> =
| MyList of 's seq
static member (>>=) : MyList<'T> * f: ('T -> MyList<'a>) -> MyList<'a>
static member Return: x: #('a0 seq) -> MyList<'a0>
val x: #('a0 seq)
val x: 'T seq
'T
val f: ('T -> MyList<'a>)
val collect: mapping: ('T -> #('U seq)) -> source: 'T seq -> 'U seq
val mappedMyList: MyList<char>