FSharpPlus


Functor

The Functor abstraction is used for types that can be mapped over. ___

Minimal complete definition

static member Map (x: 'Functor<'T>, f: 'T -> 'U) : 'Functor<'U>

Other operations

static member Unzip (x: 'Functor<'T * 'U>) : 'Functor<'T> * 'Functor<'U>

Rules

map id  =  id
map (f << g) = map f << map g

Related Abstractions

From F#+

Restricted: - string - StringBuilder - Set<'T> - IEnumerator<'T> Suggest another concrete implementation

Examples

#r @"nuget: FSharpPlus"
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])

Recommended reading

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 IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: seq<'Key * 'Value> -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> member Change: key: 'Key * f: ('Value option -> 'Value option) -> Map<'Key,'Value> ...

--------------------
new: elements: seq<'Key * 'Value> -> 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-&gt;'T-&gt;'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: seq<'T> -> '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: x: Tree<'a0> * f: ('a0 -> 'b) -> Tree<'b> static member map: 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: f: ('a -> 'a0) -> t: Tree<'a> -> Tree<'a0>
Multiple items
module Map from FSharpPlus
<summary> Additional operations on Map&lt;'Key, 'Value&gt; </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 IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: seq<'Key * 'Value> -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> member Change: key: 'Key * f: ('Value option -> 'Value option) -> Map<'Key,'Value> ...

--------------------
new: elements: seq<'Key * 'Value> -> 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: seq<'s> -> ZipList<'s>

--------------------
type ZipList<'s> = | ZipList of seq<'s> static member (<*>) : ZipList<('a -> 'b)> * ZipList<'a> -> ZipList<'b> static member Return: x: 'a -> ZipList<'a>
Multiple items
val seq: sequence: seq<'T> -> seq<'T>

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
val initInfinite: initializer: (int -> 'T) -> seq<'T>
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: seq<('a -> 'b)>
'b
val x: seq<'a>
val zip: source1: seq<'T1> -> source2: seq<'T2> -> seq<'T1 * 'T2>
val map: mapping: ('T -> 'U) -> source: seq<'T> -> seq<'U>
val mappedZipList: ZipList<string>
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: #seq<'a0> -> MyList<'a0>
val x: #seq<'a0>
val x: seq<'T>
'T
val f: ('T -> MyList<'a>)
val collect: mapping: ('T -> #seq<'U>) -> source: seq<'T> -> seq<'U>
val mappedMyList: MyList<char>