Tantric bullshit all the way down
Monad in the context of CS is a type-class which defines a polymorphic type for a a transition - a distinct computation step which, in turn, is explicitly defined via nesting of functions - the only way to establish an particular order of evaluation in a lazy language (call-by-need semantics). Just this.
The Abstraction Principle
To generalize and abstract out a pattern is to concisely express a relevant aspect of reality, without considering (referring to) particular implementation details.
Abstracting out some irrelevant details, taking particulars out of context, generalizing a notion, formally describing a pattern.
Number is The Abstraction, a pure generalized pattern if you wish. Abstract
Numbers could be specialized or categorized as different kinds (in math, which is a formalized systematic study of patterns) or types (in programming languages).
Sequence, for example, is a "right" abstraction, not too far removed from underlying reality, not too abstract.
Sequence is implying to have two ends (or starts) and therefore could be viewed (literally) as having two different particular orderings, or it could be what we call a palindrome - another abstraction which means a sequence with the same "reading" from both ends.
Even more generalizing the notion of a Sequence
map (g . f) = map g . map f
two independent passes/traversals are equivalent (the same as) single traversal of a "combined" transformation, which is called associativity law meaning that, for example, adding
2 then adding
3 is the same as adding
5 which is the composition of
contrary to abstract
Numbers function composition IS NESTING (like a cell inside of a cell, an enzyme inside of a cell)
(g . f) x = g (f x)
Generalization of List (a DNA sequence) and map (a traversing enzyme)
map :: (a -> b) -> ([a] -> [b]) when partially applied to a function
f :: a -> b on a single value (the domain and range mantra) returns (literally constructs) a function on a whole
List (whole sequence, whole thing) - a structured value
even more abstract
f :: a -> b, partially applied
map f :: M a -> M b yields (constructs) a function on
M might be, where
b could be the same type (a = b) or different (which means a morphism between different kinds of values)
M a -> M b is called a Functor (given that it satisfies the laws of identity and associativity, exactly like addition or multiplication (which is just repeated addition) of
map id just traverses a sequence, performing an identity transformation (adding of 0, multiplying by 1). it is equivalent as applying
return is just a "lifting" of a value into that higher level "kind" or "category"
List (a sequence, that thing) out of give single value
- a single apple could be viewed as a sequence of apples (only viewed, it IS NOT a sequence, no matter what idiots may scream to you) - a sequence is an abstraction of the mind
- a single atom could be viewed (by idiots) as a sequence of atoms of size 1 (a potential sequence which is bullshit). however, a DNA or RNA is a "real", "material" composition of atoms - that thing out of which a the notion of a sequence has been abstracted out.
For non-idiots a thing and a set of things of size 1 are always different kinds of values (things) and whatever is applicable to things IS NOT applicable to sets of size 1. Such application must yield a type error. This type discipline, by the way, clears the Russel Paradox. This is precicely why we always need a strong typing.
in terms of a programming language a
List of a single element (of type
a) is a
a) indeed (while an element itself is NOT) - they have different types and therefore actual representations - a value tagged with an additional type-tag -
M a -
a List of a -
Thank god, unlike idiots, we have no notion of potential or potentiality in CS.
List it is just a
cons to an empty list -
Some Category Theory bullshit
return is lifting (constructing of a value of particular kind)
map f . return = return . f
f :: a -> b is a function on values,
return :: a -> M a is a data-constructor which lifts
map f :: M a -> M b takes an
M as its argument.
. - thecomposition operator - has a lover precedence, so
map f will be evaluated first.
Again, nesting is the only way to establish an order of evaluation (serializing transitions) of functions.
f composed with
return (a data-constructor so to speak) is the same as nesting of
map f in
return which could be read as
map f after
return (check the types!) which is equivalent (the same notion as)
return and then
map f (check the ordering).
flatten in terms of nested Lists) is collapsing down by concatenation (!) one level of nesting.
map f . join = join . map (map f)
nested maps yield a function on
Lists of Lists of a, so
join [[1,2],] = [1,2,3]
See also Composition