f :: Int -> Either String Int
f 0 = Left "Zero is not allowed!"
f x = x + 42
g :: Int -> [Int]
g x | x > 1 = [1..x]
(These are functions of one argument that return an Int in a monad; Either and [] are the monads. The Error monad will bind the "Right" answer to the next function, or just return the Left answer as soon as it is produced. The List monad will bind every input list element to the function, and concatenate the resulting lists.)Then, in a dynamically typed language, nothing stops you from writing something like:
f =<< g 42
even though the expression does not make any sense. Since you don't know the type of f before you bind the output of g to it, you can't ensure that you are still in the [] monad. So while it's possible to bind [1..42] (the output of g) to f, it's not possible to make sense of the result (which would be something like Right 43 ++ Right 44 ++, except there is no ++ on Either).Anyway, this means you don't have a monad -- you just have a function that calls other functions. It's a fine way to reuse code, but it's not a monad.