Hi Cedric, Thanks for your investigation.
Regarding your guess, the code does *not* use "state monads (for mutable data)". The whole example would make sense without IO. (So this approach is *all* different from OOHaskell :-)) The IO monad is used in Poormens2 because some of the methods might want to do side effects. For instance, in the Shape example, we want to see the progress of drawing at the Console. Also, we added an extra feature to "observe" the invocation of setters. The operators (.?.) and (.!.) can be thought of as generic getters and setters. In fact, close inspection reveals that they rather model reading and writing (or call it object observation and object mutation). Mutability is achieved in Poormens2 merely by having setters. (Optionally, if you like, you *could* use the IO monad to carry around objects. Remember, in OOHaskell, the IO monad provides IORefs for mutable objects; something not used in Poormens2.) (( Some asides: If you remove the IO monad, then the Poormens2 style is really a variation on the style hinted at in Gracjan's email. One interesting difference worth noting is that Gracjan places the actual getters in classes while Poormens2 just uses overloaded functions defined in terms of the generic operators (.!.) and (.?.). But I assert that this is a detail or a minor variation point. There could be monadic and non-monadic versions in the Subtype class; I was just too lazy at that time -- assuming that one needs monads in almost all cases anyhow. (After all, we are trying to understand the migration of imperative OO code to Haskell.) You might say that the fact whether the methods (and getters and setters, say properties) are monadic or not should not disturb the general framework, whereas it does seem to affect the design of the Subtype class used in Poormens2. In particular, you might say that the result type of a getter could be just *any* type: why then expose the monadic status in the framework's types? This is needed for the generic operator (.!.). This operator captures an *in-place* update. That is, it applies the mutator to the supertype component of the datum at hand. Since the aspect of selecting that component *and* putting back the updated component is captured generically, the operator takes a type-preserving function on the supertype and lifts it to a type-preserving function on the subtype. So type preservation is in the type of the generic mutator, and we need the monadic variation on type preservation (i.e., a -> IO a) -- if we anticipate that any mutator will have side effects (in addition to those related to the mutation of the object at hand, which is just explicit in the type!!) It is then just a consistent style to provide a similarly monadic type for generic observers. )) We call this a poor mens' approach because the coding style does not allow for a direct translation of C++/C#/Java OO code -- something we aim to provide by OOHaskell (within limits of course). Ralf > -----Original Message----- > From: Cédric Paternotte [mailto:[EMAIL PROTECTED] > Sent: Monday, June 06, 2005 3:36 PM > To: Ralf Lammel > Cc: haskell-cafe@haskell.org; Gracjan Polak > Subject: Re: [Haskell-cafe] [Newbie] Quest for inheritance > > Hi Ralf, > > > I should have mentioned > > http://homepages.cwi.nl/~ralf/OOHaskell/src/PoorMens2/ > > (again *not* using OOHaskell) > > > > It's been an interesting evening. I've been having a go at your > poormen's source code and, although it's different from OOHaskell, I > still find it very similar in the sense that it's using the same > concepts, namely infix operators (for syntactic sugar I assume) and > state monads (for mutable data). But I had a look at it anyway ;) > > From what I gathered today infix operators are just like ordinary > functions, that differ only in the way you pass them parameters. I > understand the .?. and .!. operators in your code are shortcuts that > apply a function to the parent type, respectively for get and set > operations. > > The only thing I couldn't figure is the reason of using monads. I > noticed they (returnIO) were extensively used in the setters and in > the .!. operator. Do monads provide features without which this whole > thing wouldn't be possible ? What is it exactly they provide in this > context ? > > > A more general and preliminary observation: > > the entire approach is potentially more about > > object *composition* (and perhaps delegation) > > rather than inheritance. > > That's also the way I see it. > > Cédric _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe