Vedanta
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.