In programming languages, a type system is a logical system that comprises variables, expressions, functions, or modules. These types, every one in its own, form categories of sets. The main purpose of this system is, of course, to reduce possibilities for bugs defining interfaces and consistency checks. Photo by Devon Janse van Rensburg on Unsplash
`let add''' x y = x + y printfn "%A + %A  = %A" a b  (add a b )printfn "%A + %A = %A" 1 3  (add''' 1 3)Some 1 + Some 3  = Some 41 + 3 = 4printfn "%A + %A = %A" a 3  (add 1 3)This expression was expected to have type    'int option'    but here has type    'int'`

# What is a functor?

It’s an arrow between two categories C and C’,

`F: C → C'`
• exists a morphism F(f): F(x)⟶F(y) in C’ for every morphism f: x⟶y in C.
• F respects composition, i.e. F(g[f])=F(g)[F(f)] in C’ whenever g and f are composable morphisms in C.
• F sends identities to identities, i.e. F(idx)=idF(x) for all objects x in C.
`Int32 × Int32 → Int32`
`Ma(x)=x+a`
`Ma+b(x)=(Mb[Ma])(x)`
`Ma+b(x) = x+(a+b) By the definition of M           = (x+a)+b Associativity               = (Ma(x))+b By sostitution        =  Mb(Ma(x)) Definition of M by b        = (Mb[Ma])(x) Definition of Composition of Mappings`
`let (<+>) a b =    match (a, b) with    | (Some x, Some y) -> Some (x + y)    | (Some x, None)   -> Some (x)    | (None, Some y)   -> Some (y)    |    | (None, None)     -> None`
`let a = Some 1let b = [1;2;3;4]  |> List.tryFind (fun x-> x = 3)  // Some 3let c = [1;2;3;4]  |> List.tryFind (fun x-> x = 10) // None`
`let add o1 o2 =  o1 <+> o2`
`printfn "%A + %A = %A" a b (add a b)printfn "%A + %A = %A" a c (add a c)printfn "%A + %A = %A" c a (add c a)Some 1 + Some 3 = Some 4Some 1 + None = Some 1None + Some 1 = Some 1`
`add o1 o2 =  o1 <+> o2`
`let add' o1 o2 o3 =  (o1 <+> o2) <+> o3Some 1 + Some 3 + None = Some 4`
`let inline (>>) f g x = g(f x)`
`let f x = add x a let g z = add z b  let fg = g >> f    printfn "%A" (fg c) Some 4`
`let add' o1 o2 o3 =  (o1 <+> o2) <+> o3let add'' o1 o2 o3 =  o1 <+> (o2 <+> o3)printfn "%A + %A + %A = %A" a b c (add' a b c)printfn "%A + %A + %A = %A" a b c (add'' a b c)Some 1 + Some 3 + None = Some 4Some 1 + Some 3 + None = Some 4`
`printfn "%A + %A = %A" None b (add None b)printfn "%A + %A = %A" b None (add b None)None + Some 3 = Some 3Some 3 + None = Some 3`
`let opt (a:int) = Some(a)`
`printfn "%A -> %A" 3 (opt 3)3 -> Some 3`
`printfn "%A + %A = %A -> %A + %A = %A" 3 0 (3+0) (opt 3) (opt 0) ((opt 3) <+> (opt 0))3 + 0 = 3 -> Some 3 + Some 0 = Some 3`
`printfn "%A -> %A = %A + %A -> %A  + %A = %A" (3 + 4) (opt (3 + 4)) 3  4  (opt 3)  (opt 4) ((opt 3) <+> (opt 4))7 -> Some 7 = 3 + 4 -> Some 3  + Some 4 = Some 7`
`class Functor f where    fmap :: (a -> b) -> f a -> f b    (<\$) :: a -> f b -> f a`
`fmap id = id`
`fmap (f . g)  ==  fmap f . fmap g`

A complete non sequitur being.

## More from Mauro Ghiani

A complete non sequitur being.