From: Brian Mitchell Date: 2005-10-01T05:31:58+09:00 Subject: Re: In your opinion.... On 9/30/05, Christophe Grandsire wrote: > Karl von Laudermann wrote: > > > > I certainly don't understand the monad. I read some introductory > > material re: Haskell just a couple of weeks ago, out of curiosity about > > the language. My understanding of the monad concept and Haskell's use > > thereof is basically this: > > > > - Haskell is a purely functional language > > - Purely functional languages cannot have side effects > > - A language that can't do I/O is useless, so we need a way to put side > > effects into a purely functional language > > Therefore: > > - We'll put I/O subroutines into Haskell, *but* we'll call them > > "monads", and that magically fixes the problem somehow > > > > That's not quite correct. Monads are not an ad-hoc concept. They are a > mathematical concept that existed *before* Haskell was even invented. > They have their source in category theory, which is as remote from > programming as any mathematical concept can be ;) . > > There have already been good replies, but I thought I might add my two > cents here. Note that it's how I understand monads. It may not be > mathematically correct, but it seems to fit their behaviour. > > The thing about monads, and the IO monad in particular, is that they > aren't functions on objects: they are datatypes, or rather parametric > datatypes, i.e. functions that work *on types*. IO, for instance, is a > function that takes a type a, and returns a new type called "IO a". So > you can for instance take a String object, apply an IO operation to it, > and that will return a new object of type "IO String". And note that > this operation doesn't have a side-effect. It's purely functional. It's > rather that when the IO String object will be evaluated, the evaluation > will result in printing the string on the output. That is not a > side-effect, because evaluating a variable isn't an operation, but the > effect of executing a program. > > In other words, a variable of type "IO something" encapsulates an IO > action, and the IO subroutines don't have side effects by themselves, > but rather return IO actions as their result. And it's the IO action > itself, when evaluated by the Haskell interpreter/runtime (because it > needs the value of that variable to carry on its computation, like it > could need the value contained in a variable of type Integer) that will > result in some interaction with the outside world. This way, the sides > effects are contained in variables, which can only be of an IO type. > > But there's more to it. Being a pure, functional and lazy language, > Haskell doesn't have an order of execution. But IO actions need > sometimes to be ordered. Luckily, by their very mathematical > definitions, monads have to follow some axioms, which define operations > on those monads. One of those operations allows to define a > concatenation operator, which in the case of IO takes two IO actions and > returns a single IO action, which when evaluated will result in the two > IO actions to be evaluated in order. This way, you can ensure that IO > operations happen in the correct order, and to hide the mathematical > aspect of this operator called >> Haskell provides convenient syntactic > sugar (in the form of a do... end block) to write concatenations of IO > actions in a way close to imperative language. > > But monads aren't used only with IO. Another monad is the parametric > List, which if I'm not completely mistaken encapsulates linked lists. In > this case, the concatenation operator that was used with IO objects to > evaluate them orderly can be used with Lists to concatenate two Lists > into one. > > Monads are quite an esoteric feature, and my explanations probably don't > do them justice. But you can be sure they aren't just an ad-hoc > construction to pretend you don't have side effects in IO. They are a > deep mathematical concept that by chance happened to have the right > operations to be used in Haskell IO. > > As for applying something like monads to Ruby... Well, I don't know > whether this would be really necessary. The reasons why monads are > useful in Haskell (encapsulation of side effects, orderly evaluation, > collections, etc...) can be handled pretty well as they are. Moreover, > to implement them in the way Haskell does, the monad would probably have > to be defined as an operation transforming a class into another class > (in the case of IO, a class would be transformed into another class > which would have the peculiarity that when an object of that class is > evaluated by the Ruby interpreter, it results in some input or output > interaction). It would be an interesting exercise (hey, I might look > into it just for fun), but I'm afraid it would be rather academic, but > fun ;) . > -- > Christophe Grandsire. > > http://rainbow.conlang.free.fr > > You need a straight mind to invent a twisted conlang. > I've toyed with the concept myself before. Perhaps a good place to start would be Maybe... data Maybe a = Just a | Nothing Simple enough right? Brian.