3 ms·
Im not getting the idea of monads here. From my understanding monads does series of transformation( composition, unit , lift ) of a function to do its task. So
by antoaravinth 12y ago
Im not getting the idea of monads here. From my understanding monads does series of transformation( composition, unit , lift ) of a function to do its task. So does monad is similar to Adapter pattern in java? which does make two classes work even though they aren't meant to work.
Because it does transform the class/ interface to work with other class, right?
Am I missing anything here?
- efnx 12y agoI like to think of a Monad in terms of the Monad laws, it makes it much less abstract. https://www.haskell.org/haskellwiki/Monad_laws https://www.haskell.org/haskellwiki/Monad_laws Different monads can have drastically different implementations but they should all obey those laws.
- AnimalMuppet 12y agoAnd anything that obeys those laws is a monad (if I understand correctly). [Edit: And if the implementing pieces are named correctly.]
- dllthomas 12y agoI think "fmap f m = (m >>= f >>> return)" also needs to obey the functor laws. I can quickly show that "fmap id = id" follows from the monad laws, but I don't know whether "fmap (p . q) = (fmap p) . (fmap q)" does.
- dllthomas 12y agoAh, it does seem to follow: 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) m
- antoaravinth 12y agoTo be honest, I have tough time reading Haskell code or even laws. I understood the mondas in terms of javascript, as it is written over here: https://blog.jcoglan.com/2011/03/05/translation-from-haskell-to-javascript-of-selected-portions-of-the-best-introduction-to-monads-ive-ever-read/ https://blog.jcoglan.com/2011/03/05/translation-from-haskell...
- bunderbunder 12y agoIt's not quite like the Adapter pattern. Instead of adapting two different classes to work together, a monad's for extending a type to add new behavior. 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().
- dllthomas 12y agoI don't disagree with anything you said, but to pin down some concepts a tiny bit in the hopes that someone might find it helpful... 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.