August Feng

Functors

About

A Functor is simply another word for a type that where a map function can operate on, or simply said, it is mappable.

list map

The first time I encountered map and filter functions would've most likely been when writing scripts with python.

It became my bread and butter when I began coding with Lisp and Jsonnet.

Before programming with F#, my understanding of map was that it was strictly limited to lists and mapping each element with f(x) using the provided function.

(map 'list (lambda (n) (+ n 1)) '(1 2 3))

map for all

There are map functions for other types besides lists, and their implementation are specific for each one.

// Option.map
let map f =
    fun opt -> match opt with
               | Some it -> f it
               | None -> None

// Result.map
let map f =
    fun res -> match res with
               | Ok it -> f it
               | Err e -> Err e

// List.map
let map f =
    let rec inner it = match it with
                       | x :: xs -> (f x) :: (inner xs)
                       | [] -> acc
    fun it -> inner it

the properties of map

A correct map function should respect the Functor Laws.

id

The lifted function built from map id should be simply just id.

let foobar = map id
foobar ['a';'b';'c'] // = ['a';'b';'c']

The foobar function does not apply any transformations on the input ['a';'b';'c'].

compose

let f = sprintf "hello, %s"
let g = sprintf "%s!"

let h, h' = List.map f >> List.map g, List.map (salute >> punctuate)
h [ "Bar" ; "Baz" ] = h' [ "Bar" ; "Baz" ] // true