Functor Laws
identity law
If we do map identity over a functor, it should be the same as just calling identity on the functor.
map identity = identity
Or write it in another way:
map identity xs = xs
lifting the identity function (the function which returns its argument unchanged) over a structure just returns the original structure
composition law
map g (map f) = map (g <<< f)
Or write it in another way, for any functor F, the following should hold:
map g (map f F) = map (g <<< f) F
Illegal functor
Even though it's part of the Functor typeclass, it doesn't obey the functor laws and is therefore not a functor.
They aren't enforced by the programming language automatically, so you have to test them out yourself.
The type system cannot enforce the laws — they are conventions.
why laws are important?
because we can use laws to reason about behaviors that any functor should have and make functions that operate reliably on any functor.
If someone used our CMaybe type as a functor, they would expect it to obey the functor laws like a good functor. But CMaybe fails at being a functor even though it pretends to be one, so using it as a functor might lead to some faulty code.
module FakeFunctor where
import Prelude
newtype RevList a = RevList (Array a)
instance functorRevList :: Functor RevList where
map f (RevList xs) = RevList (map f (reverse xs))
We’ll use purescript-quickcheck-laws (which builds on purescript-quickcheck ).