Work In Progress Work on this post is underway... It will be done "soon..."

• Functors can only be defined over types that are `[*] => *`
• Laws:
• Identity law (identity function): `map(fa, identity) = fa`
• Composition: `map(map(fa,g), f) = map(fa, g andThen f)` or `fa.map(g andThen f) = fa.map(g).map(f)`
• Functors compose very well
• product of two functors is a functor
• Sum of two functors is a functor
• Nested functors is a functor
• Functor preserves the structure (container type). For an example a list order can’t change.
• Functor doesn’t need to be a data structure, it could be a function. Lots of data structures are functors but not all functors are data structures.
• Functors doesn’t allow you to combine programs but only to change the return type.
``````trait functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
``````

We can think of functors as a type of a programming language. For a functor `F[_]`

• `F`: A sum type of different terms
• `F[A]`: is a program in F. That is, its instructions in the `F` sum type. This program may halt of produce one or more `A` value(s).
• Map: is the ability to change the output of a parser by replacing the value captured by the program `a` by `f(a)`, where `f: A => B`

Examples

• Option
• `None` corresponds to a halt
• `Some` Emits a value
• List
• `Nil` corresponds to a halt.
• `Cons(head, tail)` recursive: Emits and then continue to the next element.

Notes

• `Nothing` has a poly-kinded… that is it satisfies `[*] => *` and `*` and `[*, *] => *`, etc.