It is time to publish some more results.
Type-level reasoning
A function application - corresponds to /Modus Ponens/
A specialization, an instance of it.
> ($) :: (a -> b) -> a -> b
> ($) f x = f x
Reversed order of agreements, still the same /Modus Ponens/
> (|>) :: a -> (a -> b) -> b
> (|>) x f = f x
"Multi-argument" is just /currying/ -- ~* ->*->*-> *~
Same, but with an explicit /abstraction barrier/ (and /lifting/)
> (>>=) :: m a -> (a -> m b) -> m b
> (>>=) ma f = undefined -- has to be defined for each particular type (an instance)
Notice that this is essentially a type-signature of ~fmap~,
> fmap :: f a ->(a->b) -> f b
with a reversed order of arguments and a specialized function.
which corresponds to a /Kleisli arrow/.
Notice also that ~($)~ and ~fmap~ differs only in having an explicit /container/.
This is not an arbitrary coincidence.
All three are essentially the same, despite funny syntax.
A basic step of logical deduction. Behind an abstraction barrier.
Composition
- of functions
> (.) :: (b -> c) -> (a -> b) -> a -> c
> (.) f g = \x -> f (g x)
- of "actions" (actual functions have to use ~return :: a -> m a~)
> (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
> (<=<) f g = undefined -- has to be defined for each particular type
or ~(>>=)~ for chaining ("flat" nesting or pipelining ) , exactly the same as ~(|>)~
Notice that the composition is /nesting/. This is the /only/ way to implement it.
The end of knowledge.