Sep 15, 2017

[FP] Functor / Applicative / Monoid / Monad

Reference:
https://github.com/fons/functional-cpp/blob/master/docs/pp-fp-2.pdf
Monoids: what they are, why they are useful, and what they teach us about software



Maybe data type:

  • Just
  • Nothing


Functor: 

Any data type that defines how map applies to it.
i.e: A C++ type that contains value and can allow a plug-in function
to work with that value.

fmap: 

fmap :: (a → b) → M a → M b

Apply functions to values that are wrapped in a context.
i.e fmap can apply plug-in function to a Functor and return the result as
a functor.

detail:
f map takes a function a → b and applies to a value of type a in context M . The
result is a value of type b in the same context. f map corresponds to mapping a
function over a container of values.



i.e
C++ type Just:

Just.map([](auto value) {return value + 42;});
class Just{
    void map(auto function){
        return Just(function(this.value));
    }
};

Or if Just contains a value with Nothing:
class Just{
    void map(auto function){
        return Just(Nothing);
    }
};

Apply a list of Just with function:
Just(list()) j;
class Just{
    void map(auto function){
        for(auto v : listvalue) {
            result.add(function(v));
        }
        return Just(result);
    }
};


Apply function to function:
class Just{
    void map(auto function){
        return Just(function(this.function(value)));
    }
};

i.e functions are functors, too.


Applicatives:

apply :: M (a → b) → M a → M b
apply a function wrapped in a context to a value wrapped in a context.

class Just{
   auto JustFunction = Just([](){});
   void map(auto Just){
        return Just(JustFunction.map(Just));
   }
};

detail:
apply uses a function a → b  'lifted' into the context M and similarly applies it
to a value in the context. Note that apply requires f map to be implemented.
apply is part of an applicative functor type class. It allows easier pipe-lining of
functions working on values in contexts.


Monads:

bind :: M a → (a → M b) → M b

Apply a function that returns a wrapped value to a wrapped value.
This function is different then oridinary function, which returns value and takes value.
This function returns context. Which contains the value and takes only value as argument.

detail:
 It takes a value in a context, and feeds that value into the function
(a → M b). bind implies the existence of apply. bind is part of the monad type
class. Note that the functions applied by f map and apply are pure functions.
bind takes a function which returns a value in a context. It allows you to combine
computations in the most flexible way.



Monoid:

Rule 1 (Closure):
The result of combining two things is always another one of the things.
Benefit: converts pairwise operations into operations that work on lists.

Rule 2 (Associativity):
When combining more than two things, which pairwise combination you do first
doesn't matter.
Benefit: Divide and conquer, parallelization, and incremental accumulation.

Rule 3 (Identity element):
There is a special thing called "zero" such that when you combine any thing
with "zero" you get the original thing back.
Benefit: Initial value for empty or missing data

Make sure your metrics are monoids

  • incremental updates
  • can handle missing data


A -> B  B-> C  
Not a Monoid, since the input/output are not same type.

Functions where the input and output are the same type are monoids.
What shall we call these kinds of functions?
“Functions with same type of input and output”  <= “Endomorphisms

All endomorphisms are monoids.


Monads are monoids:

  • Order not important (Associative)
  • Result is same kind of thing (Closure)

Monad laws:

  • The Monad laws are just the monoid definitions in diguise
    – Closure, Associativity, Identity
  • What happens if you break the monad laws?
    – You lose monoid benefits such as aggregation

A monad is just a monoid in the category of endofunctors.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.