13 ms·
A Gentle Introduction to Monad Transformers – or, Values as Exceptions
- platz 12y agoSlight nit with title: Monad Transformers can be used to model exceptions, but are more general - really they are a way to compose monads on a per-type basis (because all monads do not compose together automatically "for free" like functions or Functors). Also there are non-transformer ways to handle errors in Haskell, see: http://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/ http://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-ha...
- clhodapp 12y agoI think that the title is meant to be interpreted as "(A Gentle Introduction to Monad Transformers) – or, (Values as Exceptions)" rather than "(A Gentle Introduction to ((Monad Transformers) – or, (Values as Exceptions)))". That is, I think that the intention is to introduce the reader to monad transformers by reifying exceptions into values (and thus arriving at monad transformers), rather than to give the reader a complete understanding of monad transformers, which are (in this hypothetical world) the same thing as exception-reifying values.
- tonetheman 12y agoholy hell why are tutorials like this always in haskell. While I am sure there are a lot of people using Haskell, there is a whole lot more people in Java or python.
- Dewie 12y agoThere are a lot of tutorials around monads and monad topics using Haskell because... Haskell is one of the few languages which uses monads in a principled and explicit way.
- pekk 12y agoHaskell introduced monads as a way of solving certain problems Haskell had. So if you want to use Haskell effectively, you have to learn about monads. Monads are useful in Haskell. But that doesn't mean they are as useful in every language. So other languages don't NEED tutorials on monads as much as Haskell does. This isn't because those other languages are worse (less "principled" or "explicit") than Haskell. It's because they aren't structured to make it important to have tutorials on monads. Instead you worry about whatever the specific issues are for those other languages.
- Dewie 12y agoYeah yeah, they are all strong independent languages that don't need no monads. What do I care. EDIT: you don't strictly need something like monad transformers, though. In general, monads are just another type class. A special one since IO is implemented with them, but other than that, they are not essential.
- codygman 12y agoMonads are useful and unknowingly created in other languages all the time [0]. If you aren't quite comfortable enough with monads to follow the first link, I found this implementing monads in python tutorial[1] to be a huge help. For those that want to play with Monads in Python, check out PyMonad[2]. 0: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html http://blog.sigfpe.com/2006/08/you-could-have-invented-monad... 1: http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html http://www.valuedlessons.com/2008/01/monads-in-python-with-n... 2: https://pypi.python.org/pypi/PyMonad/ https://pypi.python.org/pypi/PyMonad/
- jerf 12y agoExpanding on the other replies, monads are not useful in most languages because most languages are not powerful enough to use them. The syntax is too heavy, because you need lots of function closures. The type system is too weak, because using monadic values without higher-kinded types is much more difficult and less useful. The fact that everybody tries to import monadic values into their languages is evidence that they would indeed be useful; the fact that such libraries are always useless in practice and incapable of even transliterating the Haskell, and often fail to even implement the full feature set of monadic values in Haskell even if you're willing to type reams of code, is why you don't use them in other languages. You don't ignore monads in non-Haskell languages because the other languages are too powerful to need them, hurr hurr Haskell is teh weaks... you ignore monads in other languages because those languages are too weak to usefully implement them. If they could, you'd see them, and I am very, very confident over the next 10 years you're going to see more and more languages coming out that really have and really use monadic values, because they will be strong enough to do so, and once you have that, the value proposition is just too good to ignore. They are too darned useful to ignore.
- rrradical 12y agoPeople that use Haskell tend to care more about this sort of thing than people that use those languages. Or alternatively, if someone cared about this sort of thing they would use Haskell.
- lsdafjklsd 12y agoMeh, I don't know or use Haskell and I'm interested in this stuff. I'm a javascript programmer introduced to these concepts via [1]https://www.youtube.com/watch?v=m3svKOdZijA https://www.youtube.com/watch?v=m3svKOdZijA and https://github.com/CrossEye/ramda https://github.com/CrossEye/ramda. Programming in a point free style in javascript is great! 1: Hey Underscore, You're Doing it Wrong!
- rrradical 12y agoFair enough, but you're thinking about checking it out now right? :) Come to the dark side. http://learnyouahaskell.com/chapters http://learnyouahaskell.com/chapters (Rambda looks neat, thanks for the link.)
- tel 12y agoThere are quite a few layers between what's discussed there and this article. In particular, static typing is an important component of monad transformer stacks, though it's possible to express them without it. Without types, however, it's hard to have a conversation about what's actually going on.
- AnimalMuppet 12y agoI might also say, people who are using Haskell have to care about this kind of stuff, because the language more or less forces it on them. Java or Python, not so much.
- codygman 12y agoSo does that mean we should just stop talking about X language that isn't nearly as popular as Java or Python? I don't see the point you are trying to make here.
- wyager 12y agoGood luck writing any sort of useful monad transformers in Java or Python.
- pekk 12y agoGood luck finding real reasons to need them in Java or Python.
- chongli 12y agoWell, you don't need shoes if you don't have feet.
- pekk 12y agoAre you implying that Java cannot be used to make useful software? What does it mean to say that Java does not have feet?
- chongli 12y agoAre you implying that Java cannot be used to make useful software? No, of course not. Are people without feet useless? What does it mean to say that Java does not have feet? It means that it lacks a capability for which it also lacks a need (shoes). This capability is that of expressing purity via the type system. Monads - and by extension, monad transformers - are a tool designed to assist the expression of imperative algorithms in a pure context. The reason I phrase it this way is because people often make the mistake of assuming Haskell is lacking expressive power due to its purity. This is untrue. Haskell is perfectly capable of expressing messy, mutable, imperative algorithms just like any other language. Other languages, on the other hand, struggle to express many of the pure algorithms and data structures used in Haskell; they simply lack the ability to enforce purity within the language and are thus reduced to purity by convention.
- AnimalMuppet 12y agoDoes lack of ability to enforce purity equal lack of ability to express the algorithm/data structure? Or does it just equal lack of ability to prove the purity?
- zak_mc_kracken 12y agoThere are plenty of monad tutorials in languages other than Haskell but Haskell is probably the language where the point of the article is not obscured by the syntactic ceremony of the language. Spend some time learning the basic Haskell syntax (it's really not that hard) and you'll be able to get to the "meat" of such articles much, much faster than if the article were written in any other language.
- javajosh 12y agoI'd really like it if foundational language/programming advocacy articles led with a few links into github usages. I mean, I suppose it's possible that it's so new that it hasn't actually been used, but honestly, if you're writing an article about it you should probably be able to link into your own examples, at least.
- codygman 12y agoThis tutorial is awesome and really tightened up a recent application I wrote. I've been trying to grok monad transformers for a while and I'm going back over the transformers paper[0] since I feel this tutorial helped things "click" for me. 0: http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf
- judk 12y agoAre Extensible Effects going to displace Monad Transformers. Oleg argues they are clearly superior.
- codygman 12y agoAny good resources on extensible effects? I'm currently reading: http://okmij.org/ftp/Haskell/extensible/index.html http://okmij.org/ftp/Haskell/extensible/index.html I also know of: http://jozefg.bitbucket.org/posts/2014-07-15-reading-extensible-effects.html http://jozefg.bitbucket.org/posts/2014-07-15-reading-extensi... However I was wondering if there was a "Gentle introduction to extensible effects". Edit: I found this presentation: http://ro-che.info/docs/2014-06-14-extensible-effects.html#1.0 http://ro-che.info/docs/2014-06-14-extensible-effects.html#1...
- brandonbloom 12y agoIt's worth looking at the Eff language, which is an OCaml variant. Much easier to understand, especially if you're monadically challenged. This paper is a great introduction to the idea of algebraic effects: http://math.andrej.com/2012/03/08/programming-with-algebraic-effects-and-handlers/ http://math.andrej.com/2012/03/08/programming-with-algebraic... Shameless plug, I gave a talk about this at the NYC "Papers We Love" meetup. Audio & slides can be found here: http://www.mixcloud.com/paperswelove/bbloom_3_17_2014_programming_with_alegebraic_effectshandlers/ http://www.mixcloud.com/paperswelove/bbloom_3_17_2014_progra...
- mercurial 12y agoI read the Eff paper, and I was blown away. I find monad transformers to be extremely clunky in comparison. The mental tax of Eff seems a lot smaller.
- thinkpad20 12y agoCan someone give an elevator pitch of extensible effects? Monad transformers are very useful and rather easy once you get used to them, although not without their downsides. What advantages do extensible effects have?
- edmack 12y agoAlso check out boxes in scala, these are lovely to use: https://www.assembla.com/wiki/show/liftweb/Box https://www.assembla.com/wiki/show/liftweb/Box
- pramalin 12y agoTry[1] in Scala standard library is also similar in concept. Erik Meijer covers this subject very well in his talks[2]. [1]The Try type represents a computation that may either result in an exception, or return a successfully computed value. http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.util.Try [2]http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote-Duality
- badman_ting 12y agoThis is very thorough, and I'm sure it's helpful to a lot of folks. So thank you to the author. For me, it's probably a syntactical issue, but I find things such as the below too hard to comprehend. What did we get just by doing this? Let's see: λ> :type EitherIO EitherIO :: IO (Either e a) -> EitherIO e a λ> :type runEitherIO runEitherIO :: EitherIO e a -> IO (Either e a) So already we have a way to go between our own type and the combination we used previously! That's gotta be useful somehow. OK, looks like a pair of parentheses moved. I have seriously no idea why that is interesting or useful. Conceptually what's going on is probably not complicated, but that syntax makes it inscrutable to me. (I could be wrong and the problem could be at a deeper level of understanding.)
- lumpypua 12y agoThey're different representations of the same thing. This is useful because we can do easy error handling in the EitherIO monad but we can't run it. We can run the IO monad but handling errors in it sucks ass. So we handle errors in EitherIO, and make it runnable (ie. convert to the IO monad) by calling runEitherIO. It's like calling a function that takes a pair when some other API gives you a two element list. The same kind of data, just munging the shape so things work. In pseudocode: // EitherIO and runEitherIO in this analogy. fun toList((a, b)) -> [a, b] fun toPair([a, b]) -> (a, b) // Gotta convert to a "runnable" pair before calling the function. var latLngList = [blah, blah] var resultPair = api1ThatRequiresPair(toPair(latLngList)) // Convert representations to do operations with a different API. api2ThatRequiresList(toList(resultPair))
- andrus 12y agoThe EitherIO data type given is data EitherIO e a = EitherIO { runEitherIO :: IO (Either e a) } But, for the sake of clarity, it can be written as data EitherIO e a = MakeEitherIO { runEitherIO :: IO (Either e a) } The author pointed out two functions that this EitherIO declaration gave us. One is a constructor, MakeEitherIO, with type IO (Either e a) -> EitherIO e a In other words, MakeEitherIO takes a value of type IO (Either e a) and returns a value of type EitherIO e a (you could think of this as "wrapping" the original IO value). The second function, runEitherIO, is an accessor function for EitherIO's named record field "runEitherIO". It has type EitherIO e a -> IO (Either e a) That is, runEitherIO takes a value of type EitherIO and returns the internal value of type IO (Either e a) (you could think of this as "unwrapping" the IO value). I hope that helps!
- maikklein 12y agoHe wrote either :: (LoginError -> Text) -> (Text -> Text) -> (Either LoginError Text -> Text) But shouldn't it be either :: (LoginError -> Text) -> (Text -> Text) -> (Either LoginError Text) -> Text
- hesselink 12y agoIn Haskell, `a -> b -> c` and `a -> (b -> c)` are the same types.
- deleted 12y ago[deleted]
- renox 12y ago> A Gentle Introduction to Monad Transformers Gentle, gentle. I didn't get it at all.