Re: [Haskell-cafe] foldl and space problems
On Mon, 2005-06-06 at 13:15 +0200, Gracjan Polak wrote: > Hello, > > My space problems continued... > > I have foldl that produces list, some combining function and quite large > source list: > > let xyz = foldl f state myBigList > > This setting should lazyli consume myBigList when next elements of xyz > are demanded. Except that it seems that myBigList is held by state to > the end of computation :( > > Question: is there any way to see what is holding my source list? I did > try to guess, but without results as of now:( foldl suffers from a fairly notorious space leak when used under lazy evaluation. Here is foldl: foldl f acc [] = acc foldl f acc (x:xs) = foldl f (f acc x) xs Here is a "symbolic" computation using it: foo = foldl g init [a,b,c] = foldl g (g init a) [b,c] = foldl g (g (g init a) b) [c] = foldl g (g (g (g init a) b) c) [] = (g (g (g init a) b) c) Notice that the "accumulator" argument grows with size proportional to the amount of list consumed. I would guess that your program is suffering from this problem. The solution? One theoretical solution is to avoid lazy evaluation in the language implementation. For instance an "optimistic" evaluator might avoid the space leak. GHC has an experimental branch that supports this, but as far as I know it has not seen an official release. A more practical solution is to force the compiler to generate more strict code. Data.List provides a function called foldl' which has the same type as foldl, but has different strictness. In particular it forces the accumulator argument to be "evaluated" before each recursive call to foldl. Unfortunately foldl' is not always as strict as you want, because it only forces the accumulator to be evaluated to what is called Weak Head Normal Form. If your accumulated value (state) has a lazy data constructor, such as the tuple constructor, you might find that the space usage remains very high. Exercise for the reader: why is this so? The solution in that case might be to add strictness flags to the arguments of the state constructors, though this may have adverse effects elsewhere in the program. > How do I debug and/or reason about such situation? Very good question. One solution is to practice your term re-writing skills and try to reason about the size of the intermediate terms that are generated. You might also find GHood useful: http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/GHood/ Cheers, Bernie. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] [Newbie] Quest for inheritance
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
[Haskell-cafe] Re: Quest for inheritance
Hi Andre, > > Manuel Chakravarty and I also wrote a paper titled "Interfacing > Haskell to Object-Oriented Languages" that you might find useful: > I've been reading it and from what I understood the technique you've come up with is used to model foreign OO language hierarchies so that Haskell can interface with them. My question is can you use it to code in Haskell in a OO way or is it just meant to provide bridges to these foreign OO objects ? I noticed most examples in the paper were related to the matters of interfacing. Or is it more than that ? Could you, for instance, craft a version of, say, the Shapes example with this approach ? Thanks, Cédric Paternotte ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
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
RE: [Haskell-cafe] [Newbie] Quest for inheritance
> Cédric Paternotte wrote: > ... > > > 5. With this : > http://www.cs.utexas.edu/ftp/pub/techreports/tr01-60/tr01-60.pdf > > > > Gracjan Polak wrote: > > I've been thinking about slight generalization of this lately. Here are > my semi-backed thoughts as of now. I should have mentioned http://homepages.cwi.nl/~ralf/OOHaskell/src/PoorMens2/ (again *not* using OOHaskell) The actual example encodes Chris Rathman's shape benchmark. The underlying story is somewhat similar to Gracjan's email. Compared to the code that Gracjan posted, - this code pinpoints another issue of this poormens' approach: get_super is quite obviously not enough if you end up wanting mutable objects. You need a setter as well. (My feeling here is that the encapsulation could be better. It would need coding effort to avoid that all data is public.) - this code also shows how the "fake inheritance through data composition" approach blends with virtual methods: one uses an extra class per abstract/virtual method. (Clearly, one can potentially try to bundle some methods in a class.) An issue here is that client code might get bloated with constraints: for datatype subtyping *and* all used virtual methods. Alternatively, one can place the OO methods (their functional counterparts) in the data capsules themselves! Then you get into the trouble of self references. A more general and preliminary observation: the entire approach is potentially more about object *composition* (and perhaps delegation) rather than inheritance. Many OO evangelists consider inheritance as a concept that was used too much in early OO times, while object composition is often more appropriate and flexible. So one *might* say that this approach does not encode a Java-inheritance solution but it does an inheritance-to-object-composition migration on the fly. So what Gracjan calls "Inherits" (and I call subtyping or substitution) is perhaps more a "delegates". Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
--- Cédric Paternotte <[EMAIL PROTECTED] > Does this mean that I was wrong in saying in my initial post that > existential types can be used to get "code inheritance" ? Or is it > just that the Shapes example has never been meant to illustrate that > side of things ? The Haskell shapes example was a recreational activity that started with Jim Weirich's challenge at: http://onestepback.org/articles/poly/ As Jim notes, inheritance was not the point of the exercise. And the Haskell example I did was somewhere in the middle of 56 other languages I had been tinkering with: http://www.angelfire.com/tx4/cus/shapes/index.html In most of the OOP languages, we tried to use code inheritance if it was available, but where it was not obvious or easily achievable (Erlang, Mercury, Clean, Haskell), it was bypassed. I did spend a bit of time trying to figure out how to get subtype polymorphism to work in Haskell, but in terms of my familiarity with the language, I am by no means proficient with the language. Best to ask Ralf about the more involed stuff. :-) > Okay, I think I've finally spotted the difference : Using existential > types you actually managed to put both CircleInstance and > RectangleInstance in the same list. I didn't notice that detail at > first. All the difference lies in that line ;) Subtypes may share some common behavior but from a top level perspective, a Rectangle type is not the same as a Circle type. Existential types allow you to treat the different types via the common behavior defined in the parent type. Without existential types, you can have only monomorphic collections. Chris Rathman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
Hi Chris, On 6 Jun 2005 14:53:11 -, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > The differences in the two shape examples doesn't have to do with code > inheritance > - it has to do with subtype polymorphism. Does this mean that I was wrong in saying in my initial post that existential types can be used to get "code inheritance" ? Or is it just that the Shapes example has never been meant to illustrate that side of things ? > Existential types allow you to > throw different subtypes into a collection and have the function dispatch > on the common superclass type. The example without existential types > demonstrates > parametric polymorphism, but not subclass polymorphism. Okay, I think I've finally spotted the difference : Using existential types you actually managed to put both CircleInstance and RectangleInstance in the same list. I didn't notice that detail at first. All the difference lies in that line ;) So I understand this is something you obviously cannot do when using classic subtyping. Incredible. This is weird, I mean that's the kind of feature I would take for granted. That makes existential types much more useful indeed. Even essential I would say. > As far as inheritance, there's actually two kinds > that occur in most OO languages. The first being type inheritance (which > really just gets you subtype polymorphism). And then there's code inheritance > - which is what you are trying to achieve. Thanks for the clarification. > At any rate, I consider > inheritance to be a convenience mechanism, and not vitally necessary to the > concepts of encapsulation, type inheritance, and polymorphism, though I > realize > that many do consider it important. Well, on the -way too big for my head- projects I'm working on, inheritance saves my life many times a day. > Chris Rathman Thanks for a lot for your time Chris, think I'm slowly starting to get the picture of all this. Cédric ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Visual Hashell Studio.NET 2005
Brian Smith wrote: Hi, When will VHS support the Visual Studio.NET 2005 Beta? I'd like to volunteer to test VHS.NET 2005 when it is available. (Also, MS is giving away the VS.NET 2005 beta for free, and VS.NET 2003 costs a whopping $15.00 from my school's bookstore). Thanks, Brian Can we use Haskell with mono? [...], Maurício ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
The differences in the two shape examples doesn't have to do with code inheritance - it has to do with subtype polymorphism. Existential types allow you to throw different subtypes into a collection and have the function dispatch on the common superclass type. The example without existential types demonstrates parametric polymorphism, but not subclass polymorphism. Generally speaking, OO programming is based on three properties (a) encapsulation; (b) inheritance; and (c) polymorphism. Well, Haskell has pretty good means of encapsulation (though I'm spoiled by ML at the moment). And existential types can get you subtype polymorphism. As far as inheritance, there's actually two kinds that occur in most OO languages. The first being type inheritance (which really just gets you subtype polymorphism). And then there's code inheritance - which is what you are trying to achieve. A language like Sather actually treats type inheritance and code inheritance as seperate things. Languages that mix the two concepts have their own set of difficulties, as the two forms of inheritance are sometimes at odds with each other. Anyhow, the classic case for code inheritance is from a re-use perspective - i.e. not having to repeat the code in multiple places. The classic problem with code inheritance is that it breaks encapsulation, as classes that reuse code from a superclass become tightly coupled with the implementation. At any rate, I consider inheritance to be a convenience mechanism, and not vitally necessary to the concepts of encapsulation, type inheritance, and polymorphism, though I realize that many do consider it important. From a Java perspective, you usually have to decide whether you want single inheritance via class extension, or multiple inheritance via interface implementation. >From the perspective of Java, the shape example that does not have code inheritance corresponds to the Java world of Interfaces - with Interfaces not allowing code inheritance. Chris Rathman --- Cédric Paternotte <[EMAIL PROTECTED] wrote: > 1. Through existential types > > As shown in the Shapes example at > http://www.angelfire.com/tx4/cus/shapes/haskell.html. > However, I couldn't spot the advantage over the standard version using > normal classes at > http://www.angelfire.com/tx4/cus/shapes/haskell98.html > > The getX function still needs to be defined in both RectangleInstance > and CircleInstance. This is not what I call inheritance. Inheritance > would make it possible to define getX only once in ShapeInstance. Or > maybe the point was only to demonstrate polymorphism. But then what is > the advantage of using existential types ? It just looks like more > work compared to the standard version that also makes use of > polymorphism. Or am I missing something ? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A Tool To Show Functions Relationship?
Dimitry Golubovsky <[EMAIL PROTECTED]> writes: > Does there exist a tool which given a Haskell source, shows functions > that are mutually recursive (i. e. call each other, even via calling > third, etc. functions)? Knowledge of that would help to split the > module into smaller modules without risk to create recursive modules. hIDE had such a tool[1], though I don't know how it worked. It's possible you could find similar functionality in either HaRe, the Haskell Refactoring Browser[2] or the Programatica toolset[3]. Maybe once the ghc-api works that sort of tool will be easy? [1] http://www.scannedinavian.org/~shae/hIDE.png [2] http://www.cs.kent.ac.uk/projects/refactor-fp/hare.html [3] http://www.cse.ogi.edu/~hallgren/Programatica/ -- It seems I've been living two lives. One life is a self-employed web developer In the other life, I'm shapr, functional programmer. | www.ScannedInAvian.com One of these lives has futures (and subcontinuations!)| --Shae Matijs Erisson ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] A Tool To Show Functions Relationship?
Does there exist a tool which given a Haskell source, shows functions that are mutually recursive (i. e. call each other, even via calling third, etc. functions)? Knowledge of that would help to split the module into smaller modules without risk to create recursive modules. For example (slightly artificial, from a parsec-based C syntax parser): declarator = try (do ps <- pointer id <- idd cp <- many cpi return (Declarator ps id cp)) "declarator" idd = try (do s <- anyIdString return (Left s)) <|> try (do tkOp "(" d <- declarator tkOp ")" return (Right d)) "idd" `declarator' and `idd' are mutually recursive, so placing them into different modules would create recursive modules. -- Dimitry Golubovsky Anywhere on the Web ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
Cédric Paternotte wrote: Hi Gracjan, This is smart. So I understand the point of this part is to forward the "function call" to the parent (through get_super). All you have to do is to define these forwards in each inheriting data. Yes. I think this is the whole point of inheritance :) Does it also mean that, in each inheriting data, you have to define these forwards to all your parents (meaning not only to the one just above, but all of them) ? In other words if I was to define a data DD which inherits from DB (and thus also from DA), will I have to define forwards for both get_a and get_b ? If not, how would you declare it ? This is exactly what I described as "private inheritance". If you have (Inherits DA DB) and (Inherits DB DC) this does not mean that you have automatically (Inherits DA DC). Why? This would require instance: instance (Inherits a b,Inherits b c) => (Inherits a c) where ... but this summons known problem: multiple inheritance. How to chose b? Imagine such situation: data DA; data DB; data DC; data DD instance Inherits DA DB where ... instance Inherits DA DC where ... instance Inherits DB DD where ... instance Inherits DC DD where ... DD inherits DA *twice*. So b in above instance declaration would not be determined uniquely. As you see there is much more writting as in Java. But this gives better control over inheritance and subsumption because everything must be stated explicitly. Multiple inheritance is allowed :) Also it is "private inheritance" (as in C++) by default. I think I like this way of dealing with inheritance. There's a bit more typing indeed and it's kind of limited but it has the advantage of being relativily simple to put in action. I agree with typing, but compared to Java this is actually not limited but more powerful, because it gives greater control over inheritance. Most important aspect to me is that inheritance can be specified *after* data declaration. Imagine you have some strange library that has DA and DB, that are obviosly in generalization-specialization hierarchy, but some jerk forgot to inherit one from another. In Java you are toast, in Haskell you can specify inheritance relation in your code :) What I really like with this is that you can come up with new data types inheriting DA without having to change anything in the declaration of DA. I guess you'd just better avoid having too many levels of hierarchy as it tends to get more and more verbose ;) If you stick to single inheritance there is other way to simulate OO in Haskell. Look for "phantom types". Whole wxHaskell (for example) is based on this concept. Cédric -- Gracjan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] foldl and space problems
Hello, My space problems continued... I have foldl that produces list, some combining function and quite large source list: let xyz = foldl f state myBigList This setting should lazyli consume myBigList when next elements of xyz are demanded. Except that it seems that myBigList is held by state to the end of computation :( Question: is there any way to see what is holding my source list? I did try to guess, but without results as of now:( How do I debug and/or reason about such situation? -- Gracjan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
Hi Ralf, On 6/6/05, Ralf Lammel <[EMAIL PROTECTED]> wrote: > Re: your enumeration. Let me add one more bullet. > In cases where inheritance is about abstract base classes > and concrete subclasses ((add interface polymorphism likewise)) > you can use a (for unknown reasons) unappreciated pattern for > extensible datatypes in Haskell: > http://homepages.cwi.nl/~ralf/OOHaskell/src/interpreter/extensible.hs > (Note: conceptually unrelated to OOHaskell) > Okay. I wasn't looking for that kind of inheritance but thanks for bringing it in. > Re: OOHaskell > Thanks for calling this a very good and thorough attempt :-) > I would really like to understand why you think that > a) this could possibly be a "huge hack" Well, please don't pay attention to my wording ;) It's only my beginner's narrow view of a paper targeted at more advanced users. That's why I added the last sentence in my initial post. I regard your work as the most comprehensive I've seen on the topic. > b) "awkward syntax" would be involved. > > Regarding a), could it be that you are overwhelmed > by the details of the implementation of OOHaskell' > *typeful* object system? Wouldn't you be similarly concerned > when looking at details of *any* other object system of *any* > other *typed* language? I certainly am. > (( We are currently massaging the OOHaskell paper. > From what you say, it might seem appropriate to emphasize > the OO programming API more clearly, while moving > implementation details of OOHaskell out of the face > of a programmer who migrates from C#/Java to Haskell. )) > > Regarding b), could it be that you would want to see > special keywords in your face, rather than thinking > in terms of records, monadic functions, open fixpoints, > closing fixpoints, ...? If yes, I guess that's an valid > desire. If there was a mainstream technique for Haskell > syntax extension, we want to use it for OOHaskell. Yes I do, as most of us would I believe. I remember you talking in the paper about adding syntactic sugar to OOHaskell to make it more convenient. That would certainly ease the path for Haskell starters. But, from what you're saying, I understand you must be hitting a wall somewhere. I don't say sugar is essential but it helps. You know I just don't feel comfortable using concepts I don't fully understand and OOHaskell relies on many advanced ones. The standard "do" notation is such a nice example of syntactic sugar, it allows you to use monads without even knowing it. The point here is that when you use the "do" notation, you don't have the feeling you're using something you don't fully master. But I'm not gonna lecture you on this ;) Regarding your paper, all I can say is that I'm not against a version targeted at more entry-level users ! This sounds like a very good idea. Otherwise, I'll certainly go back to your work, but once I got the necessary knowledge to tackle it. In the meantime I'll be keeping an eye on the project for incoming events. Slightly off-topic, but I'm sure there are many people out there, coming from the same background as mine, who have a hard time getting into Haskell just because there's no "Haskell for Java/C++/OO programmer". The ice on the cake being the Haskell way of naming its structures, that is so misleading for a Java programmer. If you knew how long it took me only to figure that Haskell names its interfaces "classes" and its classes "instances", you wouldn't believe me. Cédric ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Newbie] Quest for inheritance
Hi Gracjan, On 6/5/05, Gracjan Polak <[EMAIL PROTECTED]> wrote: > First of all, in Haskell there will be strict separation between > interfaces and data, so almost every method will be declared twice. This > is not so strange to anybody programing in Java, but for C++ programmers > can be. Inheritance relation is specified after data. There is also > separation between two concepts: what interfaces each piece of data > implements and which intefaces given interface inherits. So: I don't mind declaring functions headers more than once as long as I don't have to do it with their body. > {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-} > > module Main where > > -- general inheritance relation > class Inherits b x where > get_super :: x -> b > > -- declare interface with one method > class IA a where > get_a :: a -> Int > > -- define data with one field > data DA = DA { da_field :: Int } > > -- say how data DA conforms to interface IA > instance IA DA where > get_a x = da_field x > > -- declare some other interface IB > -- note: IB is unrelated to IA > class IB a where > get_b :: a -> String > > -- data that inherits fields of DA and adds one another field > data DB = DB { db_super :: DA, db_field :: String } > > -- DB inherits fields and methods of DA > instance Inherits DA DB where > get_super x = db_super x > > -- data DB implements interface IB > instance IB DB where > get_b x = db_field x > > -- some other random data > data DC = DC { dc_super :: DA } > > -- DC implements interface IB > instance IB DC where > get_b x = show (get_a x) > > -- and inherits DA > instance Inherits DA DC where > get_super x = dc_super x > > -- now the tricky part: state that every data x inheriting DA > -- implements all interfaces of DA (repeat for each interface) > instance (Inherits DA x) => IA x where > get_a w = da_field (get_super w) This is smart. So I understand the point of this part is to forward the "function call" to the parent (through get_super). All you have to do is to define these forwards in each inheriting data. Does it also mean that, in each inheriting data, you have to define these forwards to all your parents (meaning not only to the one just above, but all of them) ? In other words if I was to define a data DD which inherits from DB (and thus also from DA), will I have to define forwards for both get_a and get_b ? If not, how would you declare it ? > As you see there is much more writting as in Java. But this gives better > control over inheritance and subsumption because everything must be > stated explicitly. Multiple inheritance is allowed :) Also it is > "private inheritance" (as in C++) by default. I think I like this way of dealing with inheritance. There's a bit more typing indeed and it's kind of limited but it has the advantage of being relativily simple to put in action. What I really like with this is that you can come up with new data types inheriting DA without having to change anything in the declaration of DA. I guess you'd just better avoid having too many levels of hierarchy as it tends to get more and more verbose ;) Cédric ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Looking for lost library
Dean Herington wrote: > At 8:34 PM +0200 6/5/05, Gracjan Polak wrote: > >> >> Some time ago I read a beautiful paper about variables that had their >> dependencies automatically tracked and could trigger recalculation >> when changed. Prototype was implemented in OCaml, then reimplemented >> in Haskell (using monads). I would like to read that paper once again, >> but... I lost it :( > > > I believe you're describing: > http://portal.acm.org/citation.cfm?doid=581478.581482 . Yes, that is exactly what I was looking for. Thanks! > > Dean ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe