Because it does transform the class/ interface to work with other class, right?
Am I missing anything here?
Because it does transform the class/ interface to work with other class, right?
Am I missing anything here?
Think of something like Java's Iterable<T>. It takes a type T, and extends it with the concept of a sequence of items. It also gives you all sorts of extra goodies for doing useful stuff with sequences such a function to transform from a sequence of one type to a sequence of another (Iterables.transform) and Iterables.concat, which takes two instances of Iterable<T> and concatenates them.
This is close to, but not quite, what a monad really does. To get all the way there you'd want to have a function called Iterables.transformAndConcat() with a signature roughly like this:
Iterable<T> transformAndConcat(Iterable<F> from, Function<F,Iterable<T>> func)
It differs from basic transform because the function it takes maps from F to Iterable<T> rather than simply from F to T. It uses that to get a set of Iterable<T> that it then concatenates to produce the final output.This ends up being a really powerful function. It can be used to do all sorts of things, including replacing the behavior of both transform (by supplying a function that always returns an iterable of length 1 for every input) and concat (by supplying an identity function). More generally, it lets you take functions that take some input and output an Iterable of some type and compose them to produce more complex behaviors.
As a more expansive example of the concept's power, even for OO languages, let's skip over to the other managed platform: A version of this function (in this case called SelectMany) forms the core of .NET's LINQ library. LINQ's query syntax includes facilities for all sorts of SQL-style querying, including grouping and joins, and virtually all of it ends up being compiled down to calls to SelectMany(). In turn, this means that if you're writing code in C#, you can the query syntax with any generic class that conforms to a few rules, including having an implementation of SelectMany().
Java's Iterable is a "type constructor" - a function that turns types into other types. The domain of this function is any (non-primitive?) Java type. The range is things of the form Iterable<T>.
Some type constructors have a special property. In programming speak, they're "things you can sensibly map over." From a math perspective, they're one half of a functor - a "structure preserving map between categories". The type constructor maps the category's objects, we need to add a function to map arrows. In Haskell, we do that by creating an instance of Functor, where we define the function "fmap" for the specific type constructor.
For some functors, you can reasonably define a function like your "transformAndConcat" ("bind" in math and Haskell) and something that produces a singleton of whatever iterable (or the equivalent, for things that aren't containers). The triple of functor, transformAndConcat, and singleton (such that they obey the Monad laws) is a monad - in the same sense that a pair of a set and an associative operation is a semigroup.
The way math defines a monad is subtly different - they use concat (called "join" or "eta") directly, but you can define transformAndConcat using only concat and map (and concat using only transformAndConcat and id) so these are equivalent they just look a little different.
Different monads can have drastically different implementations but they should all obey those laws.
[Edit: And if the implementing pieces are named correctly.]
M1: return a >>= f = f a
M2: m >>= return = m
M3: (m >>= f) >>= g = m >>= (\ x -> f x >>= g)
(fmap f . fmap g) m = (fmap f . fmap g) m
by defn of (.) = fmap f (fmap g m)
by defn of fmap = fmap f (m >>= return . g)
by defn of fmap = (m >>= return . g) >>= return . f
by M3 = m >>= (\ x -> (return . g) x >>= return . f)
by defn of (.) = m >>= (\ x -> return (g x) >>= return . f)
by M1 = m >>= (\ x -> (return . f) (g x))
by defn of (.) = m >>= (\ x -> return (f (g x)))
by defn of (.) = m >>= (\ x -> (return . (f . g)) x)
eta reduction = m >>= return . (f . g)
by defn of fmap = fmap (f . g) m
(fmap f . fmap g) m = fmap (f . g) mI understood the mondas in terms of javascript, as it is written over here: https://blog.jcoglan.com/2011/03/05/translation-from-haskell...