RE: [Haskell-cafe] State of OOP in Haskell
Lennart wrote: OOHaskell is ingenious, but it's a terrible way to use Haskell. It's very unidiomatic Haskell, and it makes you do things in the same old OO way. It's probably obvious but let me say that ... OOHaskell is more of a proof of concept and a sandbox for OO language design. It is not a serious proposal for actual OO application development. Alexy wrote: And OOHaskell didn't compile for me on GHC 6.6... tells you about currency of use. I know a few people trying to use it. :-) Oleg and I were distracted but will update OOHaskell for 6.6 soon. Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] restricted existential datatypes
Misha, This feels like you would compose dictionary types in heterogeneous lists and then have a type-driven lookup from the dictionary list; this would be very similar to the lookup operation for TICs in the HList lib, only that the driving type is of kind *-* and that the traversing instances eventually need to be constrained by the Sat constraint for the driving type. Do you think, this could work? Best, Ralf f :: (Contains cxt ShowCxt) = Box cxt - String f (Box a) = show a The type is meant to say that the context of the box must contain Show as one of the classes. I would imagine the Contains class to be something like class Contains cxt subCxt where subDict :: cxt a - subCxt a ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] restricted existential datatypes
Did I say TICs? Assuming that you want to tuple up many constraints, I should have said TIPs of course. The SYB3 code distribution actually exercises some related chaining of contexts; cf. PairCtx. However, what's missing is the obliviousness dimension for irrelevant constraints. So you may want something like: class Sat ctx a = SatMember ctx ctx' a Let us know whether something like this works. Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell] (no subject)
[Foundations of AOP and AO languages have benefitted from the functional programming community for a while now. Haskellers, please have a look. Thanks! Ralf] Call For Papers FOAL: Foundations of Aspect-Oriented Languages 2007 A one day workshop affiliated with AOSD 2007 in Vancouver, British Columbia. Submission Deadline: 23:00 GMT, 10 January 2007 Notification of Acceptance: 2 February 2007 Final Versions of Papers Due: 1 March 2007 Workshop: 13 March 2007 Themes and Goals FOAL is a forum for research in foundations of aspect-oriented programming languages. Areas of interest include but are not limited to: * Semantics of aspect-oriented languages * Specification and verification for such languages * Type systems * Static analysis * Theory of testing * Theory of aspect composition * Theory of aspect translation (compilation) and rewriting The workshop aims to foster work in foundations, including formal studies, promote the exchange of ideas, and encourage workers in the semantics and formal methods communities to do research in the area of aspect-oriented programming languages. All theoretical and foundational studies of this topic are welcome. The goals of FOAL are to: * Make progress on the foundations of aspect-oriented programming languages. * Exchange ideas about semantics and formal methods for aspect-oriented programming languages. * Foster interest within the programming language theory and types communities in aspect-oriented programming languages. * Foster interest within the formal methods community in aspect-oriented programming and the problems of reasoning about aspect-oriented programs. Workshop Format The planned workshop format is primarily presentation of papers and group discussion. Talks will come in three categories: long (30 minutes plus 15 minutes of discussion), regular (20 minutes plus 5 minutes of discussion) and short (7 minutes plus 3 minutes of discussion). The short talks will allow for presentations of topics for which results are not yet available, perhaps for researchers who are seeking feedback on ideas or seek collaborations. We also plan to ensure sufficient time for discussion of each presentation by limiting the overall number of talks. Submissions Invitation to the workshop will be based on papers selected by the program committee; those wishing to attend but not having a paper to submit should contact the organizers directly to see if there is sufficient space in the workshop. FOAL solicits long, regular, and short papers on all areas of formal foundations of AOP languages. Submissions will be read by the program committee and designated reviewers. Papers will be selected for long, regular, and short presentation at the workshop based on their length, scientific merit, innovation, readability, and relevance. Papers previously published or already being reviewed by another conference are not eligible. Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than their paper length would otherwise command. We will limit the length of paper presentations and the number of papers presented to make sure that there is enough time for discussion. Papers presented at the workshop will be included in a technical report (from Iowa State University). Authors will retain their own copyright to the papers. Publication of papers at other venues will thus remain possible. We will also investigate having a special issue of a journal for revisions of selected papers after the workshop. Authors should note the following details: * Submissions are due no later than 23:00 GMT, 10 January 2007. (This is a firm deadline.) * Authors must indicate whether they wish to be considered for a long, regular, or short presentation. * Papers for long presentations must not exceed 10 pages in length; those for regular presentations must not exceed 7 pages in length, and those for short presentations must not exceed 3 pages in length. * Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than requested. * We encourage use of the ACM Conference format http://www.acm.org/sigs/pubs/proceed/template.html for submissions, as this will be required for accepted papers. You must add page numbers (which are not part of the standard format) to your submissions, to make adding comments easier. * Submissions are to be made to the following URL: http://continue.cs.brown.edu/servlets/foal07/continue.ss We will notify the corresponding author of papers that are selected for presentation at the workshop by 2 February 2006. Early registration for AOSD (you must register for AOSD to attend the workshop) is 9
[Haskell] Call for papers -- FOAL: Foundations of Aspect-Oriented Languages 2007
[Added a subject. Please accept my apologies! Foundations of AOP and AO languages have benefitted from the functional programming community for a while now. Haskellers, please have a look. Thanks! Ralf] Call For Papers FOAL: Foundations of Aspect-Oriented Languages 2007 A one day workshop affiliated with AOSD 2007 in Vancouver, British Columbia. Submission Deadline: 23:00 GMT, 10 January 2007 Notification of Acceptance: 2 February 2007 Final Versions of Papers Due: 1 March 2007 Workshop: 13 March 2007 Themes and Goals FOAL is a forum for research in foundations of aspect-oriented programming languages. Areas of interest include but are not limited to: * Semantics of aspect-oriented languages * Specification and verification for such languages * Type systems * Static analysis * Theory of testing * Theory of aspect composition * Theory of aspect translation (compilation) and rewriting The workshop aims to foster work in foundations, including formal studies, promote the exchange of ideas, and encourage workers in the semantics and formal methods communities to do research in the area of aspect-oriented programming languages. All theoretical and foundational studies of this topic are welcome. The goals of FOAL are to: * Make progress on the foundations of aspect-oriented programming languages. * Exchange ideas about semantics and formal methods for aspect-oriented programming languages. * Foster interest within the programming language theory and types communities in aspect-oriented programming languages. * Foster interest within the formal methods community in aspect-oriented programming and the problems of reasoning about aspect-oriented programs. Workshop Format The planned workshop format is primarily presentation of papers and group discussion. Talks will come in three categories: long (30 minutes plus 15 minutes of discussion), regular (20 minutes plus 5 minutes of discussion) and short (7 minutes plus 3 minutes of discussion). The short talks will allow for presentations of topics for which results are not yet available, perhaps for researchers who are seeking feedback on ideas or seek collaborations. We also plan to ensure sufficient time for discussion of each presentation by limiting the overall number of talks. Submissions Invitation to the workshop will be based on papers selected by the program committee; those wishing to attend but not having a paper to submit should contact the organizers directly to see if there is sufficient space in the workshop. FOAL solicits long, regular, and short papers on all areas of formal foundations of AOP languages. Submissions will be read by the program committee and designated reviewers. Papers will be selected for long, regular, and short presentation at the workshop based on their length, scientific merit, innovation, readability, and relevance. Papers previously published or already being reviewed by another conference are not eligible. Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than their paper length would otherwise command. We will limit the length of paper presentations and the number of papers presented to make sure that there is enough time for discussion. Papers presented at the workshop will be included in a technical report (from Iowa State University). Authors will retain their own copyright to the papers. Publication of papers at other venues will thus remain possible. We will also investigate having a special issue of a journal for revisions of selected papers after the workshop. Authors should note the following details: * Submissions are due no later than 23:00 GMT, 10 January 2007. (This is a firm deadline.) * Authors must indicate whether they wish to be considered for a long, regular, or short presentation. * Papers for long presentations must not exceed 10 pages in length; those for regular presentations must not exceed 7 pages in length, and those for short presentations must not exceed 3 pages in length. * Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than requested. * We encourage use of the ACM Conference format http://www.acm.org/sigs/pubs/proceed/template.html for submissions, as this will be required for accepted papers. You must add page numbers (which are not part of the standard format) to your submissions, to make adding comments easier. * Submissions are to be made to the following URL: http://continue.cs.brown.edu/servlets/foal07/continue.ss We will notify the corresponding author of papers that are selected for presentation at the workshop by 2 February 2006. Early registration for AOSD (you must
RE: [Haskell] SYB Documentation is inconclusive.
Arthur, constrFields eventually returns some mangled strings from the abstract syntax tree; see ghc-fptools/ghc/compiler/basicTypes/DataCon.lhs; and that abstract syntax promises to be order-preserving. It says (not surprisingly): dcFields :: [FieldLabel], -- Field labels for this constructor, in the -- same order as the argument types; -- length = 0 (if not a record) or dataConSourceArity. gmapQ maps the children to results. Since it is a map, it is order-preserving. There is not even any associatively business in the case of gmapQ (as opposed to gmapQl and gmapQr). So zipping together results from gmapQ and constrFields plus handling the special case of non-record types, should be just fine, no? What could possibly go wrong? Perhaps you are saying that the documentation of constrFields should promise explicitly that it does not mangle order? Let me know if I don't get what you are after ... perhaps in the café. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Arthur van Leeuwen Sent: Thursday, November 23, 2006 12:09 AM To: haskell@haskell.org Subject: [Haskell] SYB Documentation is inconclusive. L.S., lately I've been playing with Data.Generics and records. I would like to write a generic method to output to e.g. CSV files. Given MissingH.CVS that problem reduces to a generic method to take lists of records to lists of lists with shown record fields, with as first element a list of the field names. That is, something quite like: totable :: [RecordType] - [[String]] totable rs = fields (head rs) ++ map showrecord rs where fields a = constrFields . head . dataTypeConstrs . dataTypeOf $ a showrecord = gmapQ (show . toConstr) However, there are no guarantees whatsoever that the order of the fieldnames returned by constrFields corresponds to the order in which gmapQ returns the results for the children (that is the fields, in this case) of the records. Furthermore, I see no way of forcing such an order otherwise, other than writing boilerplate myself. So, is there something I just haven't seen in the lib yet, is something missing, or is just the documentation inconclusive and does the library behave as I want it to? Doei, Arthur. -- /\/ | [EMAIL PROTECTED] | Work like you don't need the money /__\ / | A friend is someone with whom | Love like you have never been hurt /\/__ | you can dare to be yourself | Dance like there's nobody watching ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: Re: [Haskell-cafe] Serialising types with existential data constructors
I start wondering, how OO languages solve the same problem. Conceptually, what is needed is a mapping of the head of the input to a type. This is indeed a recurring problem in OO languages; think of object serialization or XML/Object mapping. One common way of accomplishing the mapping is to associate custom attributes (aka annotations) with classes that exactly define when you see this element tag, instantiate this class. It is then the task of a compile-time or run-time reflection to gather these attributes and generate code from it -- code that actually constructs instances according to the mapping and the input. Klaus Ostermann and I allude to this non-trivial extensibility problem in our GPCE 2006 paper and we started to look into ways (not in that paper) to resolve the problem in a principled way. Best, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Misha Aizatulin Sent: Wednesday, September 13, 2006 8:13 AM To: haskell-cafe@haskell.org Subject: RE: Re: [Haskell-cafe] Serialising types with existential data constructors Einar Karttunen wrote: I've been using existentially quantified data constructors like data Box = forall a. Cxt a = Box a If you can include Typeable into the mix then serializing works. Serialize the value as name of type value. When deserializing use a Map name of type decoder-function and get the appropriate decoder from there for the type in question. This is indeed the only solution I see so far. It has a serious problem though: as soon as I write the mapping, I limit once and for all the set of all types that can be used with my box. And I do so in a non-extensible way - if someone later would like to use my box with some other type in it, they wouldn't be able to. In fact, I start wondering, how OO languages solve the same problem. I'll take a look at Java now. Cheers, Misha ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Where is Typing Haskell in Haskell?
Hi Mark, Cc Haskell-café, It seems the OGI links for THIH have gone dead. Is there any preferred download location for THIH these days? I couldnt spot anything. Thanks, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Can Your Programming Language Do This?
Read a sentence like this If your programming language requires you to use functors, you're not getting all the benefits of a modern programming environment. See if you can get some of your money back. If this is not a very subtle pun (regarding Java functors vs. Haskell functors), which probably it isn't, then it is another indication of sloppiness in Joel's posts on the topic of MapReduce, which he is essentially alluding to in this new post, which in turn is meant to remind us of his earlier Java rant that was very much centered around MapReduce: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html. It may be Ok that MapReduce is a misnomer (because map and reduce sound so good; so I am not complaining so much about MapReduce's name), but I sort of dislike the idea of explaining map and reduce to ordinary programmers with examples that are *not* clear-cut forms of map and reduce. Just in case, it is not obvious anyhow: MapReduce's map and reduce are not (Lisp's or Haskell's) map and reduce: - http://www.cs.vu.nl/~ralf/MapReduce - http://blogs.msdn.com/ralflammel/archive/2006/06/19/637522.aspx Ralf (obviously in pedantic mode) -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Stephane Bortzmeyer Sent: Wednesday, August 02, 2006 1:11 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Can Your Programming Language Do This? From the excellent programming blog Joel on software, a very good text if you need to convince Java or C programmers that functional programming is a A Good Thing. Probably all the readers of this list will find it brings nothing new (that's perfectly right) but it is oriented towards ordinary programmers :-) http://www.joelonsoftware.com/items/2006/08/01.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell] Paper announcement: Software Extension and Integration with Type Classes
Dear Haskellers, The following paper may still benefit from your comment. The final version is only due per 10 August 2006. Thanks, Ralf Laemmel -- http://homepages.cwi.nl/~ralf/gpce06/ Title: Software Extension and Integration with Type Classes Authors: Ralf Lämmel and Klaus Ostermann Abstract The abilities to extend a software module and to integrate a software module into an existing software system without changing existing source code are fundamental challenges in software engineering and programming-language design. We show that these challenges can be tackled, at the level of language expressiveness, by using the language concept of type classes, as it is available in the functional programming language Haskell. A detailed comparison with related work shows that type classes provide a powerful framework in which solutions to known software extension and integration problems can be provided. We also pinpoint several limitations of type classes in this context. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: incoherent instance selection when it should be still coherent
What I really find odd about it is that GHC has a notion of coherences that it tries to adhere to (and this is great), unless you ask it to violate coherence. However this specific situation is the only case that I am aware of where GHC is even incoherent when not positively instructed to may be so ... Is there some well-argued example where someone would explain why this could be at all useful? Thanks, Ralf -Original Message- From: Simon Peyton-Jones Sent: Tuesday, July 25, 2006 5:45 AM To: Ralf Lammel; glasgow-haskell-bugs@haskell.org Subject: RE: incoherent instance selection when it should be still coherent It's clear that the type checker cannot do better, because in uuh (Wrap x) (Wrap y) = bar x y the call to 'bar' can use *only* evidence stored in the Wrap constructor. Previously GHC gave an error message at this point, but some collection of users persuaded me that the behaviour below is the right one. As you say, it's not altogether clear! Simon | -Original Message- | From: [EMAIL PROTECTED] [mailto:glasgow-haskell- [EMAIL PROTECTED] | On Behalf Of Ralf Lammel | Sent: 24 July 2006 09:53 | To: glasgow-haskell-bugs@haskell.org | Subject: FW: incoherent instance selection when it should be still coherent | | Repro contained in forwarded email. | | Here is a bit more reasoning. I guess *always* selecting the generic | instance is really incoherent, and then best called a bug. Since more | specific instance selection does not make sense w/o violating the | contract of existential types, I also feel like concluding that the | program must not typecheck in the first place. I do agree that | -fallow-incoherent-instances could admit this program, if the option | was chosen (even though I generally fail to understand the use of this | option anyway :-). | | Thanks, | Ralf | | -Original Message- | From: Ralf Lammel | Sent: Friday, July 21, 2006 5:37 PM | To: 'haskell-cafe@haskell.org' | Subject: incoherent instance selection when it should be still coherent | | The following pain is sort of ghc (6.4.2) specific. | (The same behavior is achievable with hugs -98 +O which is Ok in so far | that +O (as opposed to +o) is not strongly supposed to be coherent.) | | Note the following GHC options preceding the code. | They do not contain -fallow-incoherent-instances. | | - | | {-# OPTIONS -fglasgow-exts #-} | | {-# OPTIONS -fallow-undecidable-instances #-} | | {-# OPTIONS -fallow-overlapping-instances #-} | | | -- A single parameter class with two silly instances | | class Foo x where foo :: x - (); foo = const () | | instance Foo () | | instance Foo Bool | | | -- A two-parameter class with a generic and a non-generic instance | | class (Foo x, Foo y) = Bar x y where bar :: x - y - String | | instance (Foo x, Foo y) = Bar x y where bar _ _ = generic instance | | instance Foo z = Bar () z where bar _ _ = non-generic instance | | | -- An existential wrapper around foos | | data Wrap = forall x. Foo x = Wrap x | | | -- A wrapper-based variation on the type-class member bar | | uuh :: Wrap - Wrap - String | | uuh (Wrap x) (Wrap y) = bar x y | | | -- Let's try all unwrapped and wrapped combinations of bar and uuh | | t1 = () | | t2 = True | | w1 = Wrap t1 | | w2 = Wrap t2 | | main = do | print $ bar t1 t1 | print $ uuh w1 w1 -- uuh! | print $ bar t1 t2 | print $ uuh w1 w2 -- uuh! | print $ bar t2 t1 | print $ uuh w2 w1 | print $ bar t2 t2 | print $ uuh w2 w2 | | | | We get: | | {- | | non-generic instance | generic instance | non-generic instance | generic instance | generic instance | generic instance | generic instance | generic instance | | -} | | This means that the generic instance is consistently chosen by uuh. | This is clearly incoherent. | I would also complain that uuh type-checks in the first place. | Opinions? | | Regards, | Ralf | | ___ | Glasgow-haskell-bugs mailing list | Glasgow-haskell-bugs@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem
Bulat, Dmitri is not necessarily mixing [...] class and its (default) instance. Bulat, one could suspect a reasonable use of default class methods: http://www.haskell.org/onlinereport/decls.html#overloading Indeed, Dmitri's declarations make sense as default class methods. ... except for Jared's observation: the attempt to rely on Ord. If % in place of was used on the RHSs, then this would really look like default methods. Ralf PS: We don't want to send people using overlapping instances more often than necessary :-) -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Bulat Ziganshin Sent: Tuesday, July 25, 2006 9:46 AM To: Dmitri O.Kondratiev Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem Hello Dmitri, Tuesday, July 25, 2006, 8:15:41 PM, you wrote: class Eq a = MyOrd a where (%=), (%), (%=) :: a - a - Bool x %= y = (x y || x == y) x % y = y x x %= y = (y x || x == y) you are mixing definition of class and its (default) instance. try the following: class Eq a = MyOrd a where (%=), (%), (%=) :: a - a - Bool instance Ord a = MyOrd a where x %= y = (x y || x == y) x % y = y x x %= y = (y x || x == y) although i don't think it is what you want. actually Haskell don't have a good way to define default instance for some subclass, although there are some proposals how this can be addressed. you should either define exactly one instance for all Orded types or duplicate this trivial definition in every instance. in GHC you also has an option to use overlapping instances but this can work only if all your other instance definitions don't use deriving from typeclasses. i.e. the following is prohibited: class Eq a = MyOrd a where ... instance Ord a = MyOrd a where ... instance SomeClass a = MyOrd a where ... and even if you will be accurate, i'm not sure that overlapping will work properly ps: you can ask me in Russian via private mail -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] incoherent instance selection when it should be still coherent
The following pain is sort of ghc (6.4.2) specific. (The same behavior is achievable with hugs -98 +O which is Ok in so far that +O (as opposed to +o) is not strongly supposed to be coherent.) Note the following GHC options preceding the code. They do not contain -fallow-incoherent-instances. {-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-overlapping-instances #-} -- A single parameter class with two silly instances class Foo x where foo :: x - (); foo = const () instance Foo () instance Foo Bool -- A two-parameter class with a generic and a non-generic instance class (Foo x, Foo y) = Bar x y where bar :: x - y - String instance (Foo x, Foo y) = Bar x y where bar _ _ = generic instance instance Foo z = Bar () z where bar _ _ = non-generic instance -- An existential wrapper around foos data Wrap = forall x. Foo x = Wrap x -- A wrapper-based variation on the type-class member bar uuh :: Wrap - Wrap - String uuh (Wrap x) (Wrap y) = bar x y -- Let's try all unwrapped and wrapped combinations of bar and uuh t1 = () t2 = True w1 = Wrap t1 w2 = Wrap t2 main = do print $ bar t1 t1 print $ uuh w1 w1 -- uuh! print $ bar t1 t2 print $ uuh w1 w2 -- uuh! print $ bar t2 t1 print $ uuh w2 w1 print $ bar t2 t2 print $ uuh w2 w2 We get: {- non-generic instance generic instance non-generic instance generic instance generic instance generic instance generic instance generic instance -} This means that the generic instance is consistently chosen by uuh. This is clearly incoherent. I would also complain that uuh type-checks in the first place. Opinions? Regards, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell] Google SoC: Software Transactional Memory for Parrot
Bulat wrote: it seems that Haskell continues to be a source of new technologies for other languages. i will wait for GADT for C# :) No need to wait: http://doitest.acm.org/10.1145/1094811.1094814 We show that existing object-oriented programming languages such as Java and C# can express GADT definitions, and a large class of GADT-manipulating programs, through the use of generics, subclassing, and virtual dispatch. However, ... Ralf ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell-cafe] RE: why isn't everything an instance of Data?
Hi Frederik, Cc Haskell-café as proposed by Frederik, Why isn't everything an instance of Data? It seems natural to give every type which is defined via 'data' an automatic Data instance. This would make implementing many things much simpler. Certain types such as functions would only be able to have stub instances, for instance not allowing traversal of constructor arguments, but this would no more hurt the user than not having such instances defined in the first place. To clarify, what I am suggesting is that Data no longer be a class but an interface - one would be able to call 'toConstr' on any type. [Ralf Lammel] I get your overall question but let me ask about one detail. When you say an interface, what does this mean in the Haskell sense (where normally a type-class is like an OO interface *anyhow*)? Is there a fear that this would lead to sloppy programming? [Ralf Lammel] I agree that it could be convenient to assume gfoldl and all that as true primitives. Personally, I wouldn't necessarily like that: Haskell's type system seems to be designed to (mostly) distinguish parametrically polymorphic functions from the rest; just as much as it (mostly) makes explicit any effects involved in a computation. Also, how would these primitives need to be implemented? We would need a whole lot of type information in the sense of reflection to be around at run-time. Also, it would be nice if it were possible to have the compiler infer, in a function such as cast :: a - Maybe b that 'a' and 'b' are instances of the same classes. However, unless I'm mistaken this would require 'cast' to have special status with the compiler (or for there to be some new syntax allowing one to indicate that two type variables implement the same classes). [Ralf Lammel] There are several problems here. First, I doubt that we want to establish that 'a' and 'b' are instances of the same classes. That sounds like a too special case. I guess we would want to establish that a given type instantiates a given type class. Second, our new cast operation (which would indeed be very much like an OO down-cast) would need to be a special primitive indeed, including special syntax. If we had first-class type-classes, special syntax is not needed, but we would still need a primitive for the actual cast. Third, we need to come up with some fairly tricky means of getting the dictionary for a type out of the blue at run-time. This would be sort of possible (certainly for monomorphic types) if we had the type of the value/expression around at run-time, so that we can use it to look up a dictionary from a global pool. However, that type is not available without extra effort. To summarize, if this was the question, this expectation seems to lead pretty far away from what we have in Haskell and likely to get anywhere soon -- as far as I can tell. But without such inferences, the Generics stuff has limited usefulness - so much in Haskell is based on classes, but the only class one can use in the argument of say 'everywhere' is Data itself: everywhere :: (forall a . Data a = a - a) - forall a . Data a = a - a [Ralf Lammel] There are two stories here: a) Any type-specific case can make any amount of type-class assumptions even in the original SYB1 style. This gets you pretty far in practice. b) If you want to write generic functions whose set of types is characterized by a designated type class, then you need to use SYB3 style. HTH, Ralf PS: Some related stuff ... - I uploaded a new SYB paper recently: http://www.cwi.nl/~ralf/syx/ - We also updated the SYB site to include other people's SYB papers: http://www.cs.vu.nl/boilerplate - See Pablo Nogueira's paper Context-Parametric Polykinded Types for some interesting GH-related issues on type classes; http://www.cs.nott.ac.uk/~pni/Papers/ - Finally, I plan to use my new blog for Haskell-related stuff as well: http://blogs.msdn.com/ralflammel/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Writing an extensible interpreter
Hi David, Readers on this list will not be surprised to hear me saying that, of course, type classes perfectly make sense for your scenario. You may have a look at some posts on extensible interpreters: - http://compilers.iecc.com/comparch/article/04-12-111 - http://www.haskell.org/pipermail/haskell/2005-February/015346.html There are at least two ways of making the type [Step] - String work with a setup that replaces Step by a type class. One is: use an existential type; another is: use HLists. (There is a third one: use Typeable.) I'll send you some draft material in a separate email that I don't want to share publicly yet. In this draft, your scenario is actually illustrated in a broader context. And then I should mention that you may also want to have a look at Hinze's and Loeh's open data types. I seem to remember that they provide actual tool support (sort of preprocessing) so that this works with Haskell today. HTH Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of David House Sent: Sunday, May 21, 2006 5:50 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Writing an extensible interpreter Hi all. I'm in the process of writing an interpreter for the self-modifying automaton languages SMATINY [1], designed by ihope (whose name some of you may recognise from IRC). The current effort is online [2], but it's at a rather early stage and there's a few modifications I'd like to make to it. To begin with, extensibility is key. Such tiny languages are designed to be easily extendable, and I'd like my interpreter to follow suit. At the moment, adding a new command is as follows: 1) Add a new constructor for the Step type to represent your command. 2) Write a Parsec parser for your command in Smatiny.hs. 3) Add said parser to the 'inputs' list in Smatiny.hs. 4) Write a 'handler' for your command; a function in State that will take the appropriate action. This is a bit of an ordeal; I'd like new commands to be addable without touching Smatiny.hs, which will form the base of the interpreter. One solution I was thinking about was to write a new module for each command that exports a parser and handler function. A bit of metacode would read the Commands directory then import qualified all the modules it finds in there. Subsequently, it would call parseSmatiny (the parser; in Smatiny.hs) with all the parsers it found as an argument, then send the output of this into runSmatiny (the interpreter; also in Smatiny.hs). However, the remaining issue is step 1): how would the metacode handle additional constructors to the Step ADT? Type classes won't work here: the intepreter has a type of [Step] - String. With type classes this would have a type of something like Step a = [a] - String, but by the homogeneity of lists you'd only be able to have one type of step in your program. Thanks in advance for your input. Let me know if I didn't explain something too well; I have a tendancy toward brevity :) [1]: http://esoteric.voxelperfect.net/wiki/SMATINY [2]: http://esoteric.voxelperfect.net/files/smatiny/impl/smatiny.tar.gz -- -David House, [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell] Ambiguous type variable when using Data.Generic
Bas, There is a really easy (and intended) way to make this work. See Sec. 6.4 SYB1 paper (TLDI 2003). - You compose things as follows: simplify = id `extT` simplifyRhs `extT` simplifyExp `extT` ... - You apply everything right away to simplify. There is no need to use a class in your case. However, if you really want to you need to apply the pattern from the SYB3 paper. BTW, simplifications are often not of the kind that non-descending step functions and recursion by everything does the right thing. Often you need a more powerful schemes such as bottom-up innermost normalization (some variation thereof). Please see the Stratego and Strafunski literature for this purpose. Best, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Bas van Dijk Sent: Saturday, May 20, 2006 7:50 AM To: haskell@haskell.org Subject: [Haskell] Ambiguous type variable when using Data.Generic Hello, I'm writing a function 'preProcess' that simplifies the AST that comes out of Language.Haskell.Parser.parseModule. Simplifying means rewriting infix applications to normal prefix applications (in both patterns and expressions), removing parentheses, rewriting guards to if-then-else expressions, etc.. At the moment I use Data.Generic to traverse the AST and apply simplification functions to the different values. Like this: -- - preProcess :: HsModule - HsModule preProcess = em simplifyRhs . em simplifyPat . em simplifyExp where em f = everywhere (mkT f) simplifyExp :: HsExp - HsExp simplifyExp (HsInfixApp e1 op e2) = HsApp (HsApp (opToExp op) e1) e2 simplifyExp (HsLeftSection e op)= HsApp (opToExp op) e simplifyExp (HsRightSection op e) = HsApp (opToExp op) e simplifyExp (HsParen e) = e simplifyExp e = e opToExp (HsQVarOp name) = HsVar name opToExp (HsQConOp name) = HsCon name simplifyPat :: HsPat - HsPat simplifyPat (HsPInfixApp p1 consName p2) = HsPApp consName [p1, p2] simplifyPat (HsPParen p) = p simplifyPat p = p simplifyRhs :: HsRhs - HsRhs simplifyRhs (HsGuardedRhss rhss) = HsUnGuardedRhs $ makeIf rhss where makeIf :: [HsGuardedRhs] - HsExp makeIf [] = nonExhaustivePatternError makeIf (HsGuardedRhs _ con exp : rhss) = HsIf con exp $ makeIf rhss nonExhaustivePatternError = HsApp (HsVar (UnQual (HsIdent error))) (HsLit (HsString Non-exhaustive patterns)) simplifyRhs rhs = rhs -- - This works, however I would like to have a single function 'simplify' that can be applied to different values in the AST. This calls for a class Simplify with instances for expressions, patterns, etc.: -- - preProcess :: HsModule - HsModule preProcess = everywhere (mkT simplify) class Simplify a where simplify :: a - a instance Simplify HsExp where simplify (HsInfixApp e1 op e2) = HsApp (HsApp (opToExp op) e1) e2 simplify (HsLeftSection e op)= HsApp (opToExp op) e simplify (HsRightSection op e) = HsApp (opToExp op) e simplify (HsParen e) = e simplify e = e instance Simplify HsPat where simplify (HsPInfixApp p1 consName p2) = HsPApp consName [p1, p2] simplify (HsPParen p) = p simplify p = p instance Simplify HsRhs where simplify (HsGuardedRhss rhss) = HsUnGuardedRhs $ makeIf rhss where makeIf :: [HsGuardedRhs] - HsExp makeIf [] = nonExhaustivePatternError makeIf (HsGuardedRhs _ con exp : rhss) = HsIf con exp $ makeIf rhss nonExhaustivePatternError = HsApp (HsVar (UnQual (HsIdent error))) (HsLit (HsString Non-exhaustive patterns)) simplify rhs = rhs opToExp (HsQVarOp name) = HsVar name opToExp (HsQConOp name) = HsCon name -- - However, compiling the above gives the following type error: Ambiguous type variable `b' in the constraints: `Typeable b' arising from use of `mkT' at Special.hs:145:25-27 `Simplify b' arising from use of `simplify' at Special.hs:145:29-36 Probable fix: add a type signature that fixes these type variable(s) How can I make this work? Greetings, Bas van Dijk ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Last call for papers: RULE-BASED PROGRAMMING 2006
RULE'06, 7th International Workshop on Rule-Based Programming, 11th August, 2006, Seattle, USA, A Satellite Event of RTA http://www.dcs.kcl.ac.uk/events/RULE06/ IMPORTANT DATES - 14th May, 2006 Deadline for electronic submission of papers - 15th June, 2006 Notification of acceptance of papers - 30th June, 2006 Deadline for final versions of accepted papers - 11th August, 2006 Workshop INVITED SPEAKERS Joint RULE and WRS keynote speakers: - Dick Kieburtz, OHSU/OGI School of Science Engineering - Claude Kirchner, INRIA and LORIA RULE-BASED PROGRAMMING The rule-based programming paradigm is characterized by the repeated, localized transformation of a data object such as a term, graph, proof, constraint store, etc. The transformations are described by rules which separate the description of the object to be replaced (the pattern) from the calculation of the replacement. Optionally, rules can have further conditions that restrict their applicability. The transformations are controlled by explicit or implicit strategies. The basic concepts of rule-based programming appear throughout computer science, from theoretical foundations to practical implementations. Term rewriting is used in semantics in order to describe the meaning of programming languages, as well as in the implementation of program transformation systems. Rules are used implicitly or explicitly to perform computations, e.g., in Mathematica, OBJ, ELAN, Maude or to perform deductions, e.g., by using inference rules to describe or implement a logic, theorem prover or constraint solver. Mail clients and mail servers use complex rules to help users organising their email and sorting out spam. Language implementations use bottom-up rewrite systems for code generation (as in the BURG family of tools.) Constraint-handling rules (CHRs) are used to specify and implement constraint-based algorithms and applications. Rule-based programming idioms also give rise to multi-paradigm languages like Claire. TOPICS We solicit original papers on all topics of rule-based programming, including: - Languages for rule-based programming * Expressivity, Idioms, Design patterns * Semantics, Type systems * Implementation techniques * System descriptions - Other foundations * Complexity results * Advances on rewriting logic * Advances on rewriting calculus * Static analyses of rule-based programs * Transformation of rule-based programs - Applications of rule-based programming, e.g.: * Program transformation * Software analysis and generation * System Control * Work-flow control * Knowledge engineering - Combination with other paradigms * Functional programming * Logic programming * OO programming * Language extensions * Language embeddings - System descriptions SUBMISSIONS Papers (of at most 15 pages) should be submitted electronically via the web-based submission site. http://www.easychair.org/RULE2006/ Any problems with the submission procedure should be reported to one of the PC chairs: Maribel Fernandez ([EMAIL PROTECTED]), Ralf Lämmel ([EMAIL PROTECTED]) PROCEEDINGS Accepted papers will be published in the preliminary proceedings volume, which will be available during the workshop. The final proceedings will be published in Electronic Notes in Theoretical Computer Science (ENTCS), Elsevier. PROGRAMME COMMITTEE - Mark van den Brand (TU Eindhoven, Netherlands) - Horatiu Cirstea (LORIA, France) - Pierre Deransart (INRIA Rocquencourt, France) - Michael L. Collard (Kent State University, USA) - Martin Erwig (Oregon State University, USA) - Francois Fages (INRIA Rocquencourt, France) - Maribel Fernandez (Co-Chair, King's College London, UK) - Jean-Pierre Jouannaud (LIX, Ecole Polytechnique, France) - Oleg Kiselyov (FNMOC, USA) - Ralf Lämmel (Co-Chair, Microsoft, USA) - Ugo Montanari (Universita di Pisa, Italy) - Pierre-Etienne Moreau (LORIA, France) - Tobias Nipkow (Technical University Munich, Germany) - Tom Schrijvers (K.U.Leuven, Belgium) - Martin Sulzmann (National University of Singapore, Singapore) - Victor Winter (University of Nebraska at Omaha, USA) ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell-cafe] RE: generics question 2
Hi Frederik, [resending; as it bounced because of size.] That’s a tricky one. Let’s first recall that this one is still fine: *Main :t cast True :: (Typeable a, Typeable b) = Maybe (a,b) cast True :: (Typeable a, Typeable b) = Maybe (a,b) :: (Typeable b, Typeable a) = Maybe (a, b) The type error for your attempt was caused by the attempt to print this polymorphic maybe. The overloading resolution for the show instance cannot possibly deal with this polymorphism. More generally, any dependent SYB functionality or class-based code would run into this problem. However, the above polymorphic cast, as such does not work as you would expect. Here is a clear example: sigh = maybe 0 (\(a,b) - gsize a + gsize b) (cast True) The component types of this product are *ambiguous*. Cast is monomorphic. No way to use it for polymorphic problems. So we need polymorphic type extension, here: dataCast2 provided by the Data class. So here is how it works with polymorphic type extension. See below and check out the 2nd paper for some deeper discussion. Or if you find this all too complicated, use class-based SYB style (3rd SYB paper). Thanks for keeping me off the street. ☺ Regards, Ralf import Data.Generics -- -- A weird gsize function -- g :: Data a = a - Int g = gsize `extQ` (\(x::Int) - x) `ext2Q` f where f :: (Data a, Data b) = (a,b) - Int f (a,b) = g a + g b + 1 -- -- | Flexible type extension -- Should be in Data.Generics.Aliases -- ext2 :: (Data a, Typeable2 t) = c a - (forall a b. (Data a, Data b) = c (t a b)) - c a ext2 def ext = maybe def id (dataCast2 ext) -- -- | Type extension of transformations for unary type constructors -- Should be in Data.Generics.Aliases -- ext2T :: (Data d, Typeable2 t) = (forall d. Data d = d - d) - (forall d d'. (Data d, Data d') = t d d' - t d d') - d - d ext2T def ext = unT ((T def) `ext2` (T ext)) -- -- | Type extension of queries for type constructors -- Should be in Data.Generics.Aliases -- ext2Q :: (Data d, Typeable2 t) = (d - q) - (forall d d'. (Data d, Data d') = t d d' - q) - d - q ext2Q def ext = unQ ((Q def) `ext2` (Q ext)) -- -- | The type constructor for transformations -- Not exported from Data.Generics.Aliases -- newtype T x = T { unT :: x - x } -- -- | The type constructor for queries -- Not exported from Data.Generics.Aliases -- newtype Q q x = Q { unQ :: x - q } -- -- Time to test -- data Foo = Foo1 Int | Foo2 (Int,Int) deriving (Typeable, Data, Show) main = do print $ gmapQ g (Foo1 88) print $ gmapQ g (Foo2 (21,20)) -Original Message- From: Frederik Eaton [mailto:[EMAIL PROTECTED] What I want to do is specialise not to a specific type like Bool but to the class of all pairs (a,b). But this causes the compiler to complain, even for simpler examples: cast True :: (Typeable a, Typeable b) = Maybe (a,b) interactive:1:0: Ambiguous type variable `a' in the constraints: `Typeable a' arising from instantiating a type signature at interactive:1:0-51 `Show a' arising from use of `print' at Top level Probable fix: add a type signature that fixes these type variable(s) interactive:1:0: Ambiguous type variable `b' in the constraints: `Typeable b' arising from instantiating a type signature at interactive:1:0-51 `Show b' arising from use of `print' at Top level Probable fix: add a type signature that fixes these type variable(s) Is there a way to solve this, or do I have to avoid polymorphism? I can use 'toConstr' to find out dynamically if a particular type is a pair, and then use unsafeCoerce, but I hear that unsafeCoerce is unsafe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: generics question 2
Hi Ralf, I'm looking for a function like extT but with more general type: (t a - s a) - (t b - s b) - (t a - s a) Is there such a thing in the generics library? Hi Frederik, Not sure how you are exactly going to use such an operation ... But here is its implementation anyhow. Thanks for the riddle. Ralf import Data.Generics -- Frederik's weird ext operation :-) ext' :: (Data (t a), Data (s a), Data (t b), Data (s b)) = (t a - s a) - (t b - s b) - (t a - s a) ext' f g ta = case cast g of Just g' - g' ta Nothing - f ta -- A generic default f (Just x) = [x] f Nothing = [] -- A type-specific case g (Just True) = [True] g (Just False) = [] g Nothing = [] -- A composition using our new type-extension operator test :: Data a = Maybe a - [a] test = ext' f g -- Let's see whether it works ... main = do print $ test (Just (1::Int)) print $ test (Just False) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell] RULE 2006 at FLoC --- paper deadline 14 May
== Call for Papers RULE 2006 7th International Workshop on Rule-Based Programming http://www.dcs.kcl.ac.uk/events/RULE06/ Seattle, USA 11th August 2006 A satellite event of RTA 2006 at FLoC === The basic concepts of rule-based programming appear throughout Computer Science, from theoretical foundations to practical implementations. Term rewriting is used in semantics in order to describe the meaning of programming languages, as well as in the implementation of program transformation systems. Rules are used implicitly or explicitly to perform computations, e.g., in Mathematica, OBJ, ELAN, Maude or to perform deductions, e.g., by using inference rules to describe or implement a logic, theorem prover or constraint solver. Mail clients and mail servers use complex rules to help users organising their email and sorting out spam. Language implementations use bottom-up rewrite systems for code generation (as in the BURG family of tools.) Constraint-handling rules (CHRs) are used to specify and implement constraint-based algorithms and applications. Rule-based programming idioms also give rise to multi-paradigm languages like Claire. The purpose of this workshop is to bring together researchers from the various communities working on rule-based programming to foster advances in the theory of rule-based programming, cross-fertilization between theory and practice, research on rule-based programming methods, and the exploration of important application domains of rule-based programming. RULE 2006 will be a one-day satellite event of RTA 2006 at FLoC. Topics of interest -- * Languages for rule-based programming - Expressive power, Idioms, Design patterns - Semantics, Type systems - Implementation techniques - System descriptions * Other foundations - Complexity results - Advances on rewriting logic - Advances on rewriting calculus - Static analyses of rule-based programs - Transformation of rule-based programs * Applications of rule-based programming, e.g.: - Program transformation - Software analysis and generation - System Control - Work-flow control - Knowledge engineering - System descriptions * Combination with other paradigms - Functional programming - Logic programming - OO programming - Biocomputing - Language extensions - Language embeddings Submissions and Publication: Papers (of at most 15 pages) should be submitted electronically via the submission page: http://www.easychair.org/RULE2006 Any problems with the submission procedure should be reported to one of the PC chairs: [EMAIL PROTECTED], [EMAIL PROTECTED] Accepted papers will be published in the preliminary proceedings volume, which will be available during the workshop. The final proceedings will be published in Electronic Notes in Theoretical Computer Science (ENTCS), Elsevier. IMPORTANT DATES - 14th May 2006: Deadline for electronic submission of papers - 15th June 2006: Notification of acceptance of papers - 30th June 2006: Deadline for final versions of accepted papers - 11th August 2006: Workshop Programme Committee: - Mark van den Brand (TU Eindhoven, Netherlands) - Horatiu Cirstea (LORIA, France) - Pierre Deransart (INRIA Rocquencourt, France) - Michael L. Collard (Kent State University, USA) - Martin Erwig (Oregon State University, USA) - Francois Fages (INRIA Rocquencourt, France) - Maribel Fernandez (Co-Chair, King's College London, UK) - Jean-Pierre Jouannaud (LIX, Ecole Polytechnique, France) - Oleg Kiselyov (FNMOC, USA) - Ralf Laemmel (Co-Chair, Microsoft, USA ) - Ugo Montanari (Universita di Pisa, Italy) - Pierre-Etienne Moreau (LORIA, France) - Tobias Nipkow (Technical University Munich, Germany) - Tom Schrijvers (K.U.Leuven, Belgium) - Martin Sulzmann (National University of Singapore, Singapore) - Victor Winter (University of Nebraska at Omaha, USA) ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] The Haskell road ... to Google
Two new papers available: Book review The Haskell Road to Logic, Maths and Programming by Kees Doets and Jan van Eijck To appear in JoLLI journal; 13 pages. http://www.cs.vu.nl/~ralf/JoLLI06 Executive summary: The Haskell road is an excellent book worth considering as course material and reading anyhow. A non-Haskell road is also discussed in the review. Google's MapReduce Programming Model -- Revisited Draft; To be submitted; feedback appreciated; 27 pages. http://www.cs.vu.nl/~ralf/MapReduce Executive summary: The seminal MapReduce paper had been briefly discussed at LTU without really going into technical details. The present paper discovers the concepts from a functional programming perspective. Did you ever wonder why MapReduce is called MapReduce? Ralf Laemmel ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] ST monad
... for the same reason as this one doesn't get through: import Control.Monad.ST import Data.Array.ST main = print $ runST $ do return () ... but this one does: import Control.Monad.ST import Data.Array.ST main = print $ runST ( do return ()) it's all about rank-2 types; see SPJ's et al. paper on type inference for these types. However, I guess that the jury is still out, say this specific rank-2 behavior may be revised (and I also hope so). HTH Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Bulat Ziganshin Sent: Tuesday, January 03, 2006 2:28 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] ST monad Hello the following code can't go through typechecking. can anyone help me to fix it or, better, let me know what i need to read to fix it myself? :) import Control.Monad.ST import Data.Array.ST main = print $ runST $ do arr - newArray (1,10) 127 a - readArray arr 1 writeArray arr 1 216 b - readArray arr 1 return (a,b) PS: error message is b.hs:4:15: Inferred type is less polymorphic than expected Quantified type variable `s' escapes Expected type: ST s a - b Inferred type: (forall s1. ST s1 a) - a In the first argument of `($)', namely `runST' In the second argument of `($)', namely `runST $ (do arr - newArray (1, 10) 127 a - readArray arr 1 writeArray arr 1 216 b - readArray arr 1 return (a, b))' -- Best regards, Bulat mailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: missing Data instances
Simon PJ, Is that Ok? Should I? Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:glasgow-haskell- [EMAIL PROTECTED] On Behalf Of Frederik Eaton Sent: Thursday, December 29, 2005 11:39 AM To: glasgow-haskell-bugs@haskell.org Subject: missing Data instances These don't seem to have Data instances in 6.4.1: Language.Haskell.TH.Exp Data.Tree.Tree I guess there are probably a lot more, I just ran into these today. Is there anything which prevents proper 'deriving' clauses from being added to their definitions? Frederik ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: [Haskell] Hlist distribution -- compiler error in TIP
Dear Frank, HList is definitely tested with 6.4. See transcript below. My guess would be that you are perhaps not running with options as stated in the Makefile. Anyway, if your problems persist, I am happy to take this offline. Merry Christmas, Ralf [EMAIL PROTECTED] ~/projects/HList/src $ ghc --version The Glorious Glasgow Haskell Compilation System, version 6.4 [EMAIL PROTECTED] ~/projects/HList/src $ make test ghci -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances MainGhcGeneric1.hs -v0 Main.in MainGhcGeneric1.out diff -b MainGhcGeneric1.out MainGhcGeneric1.ref ghci -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances MainGhcTTypeable.hs -v0 Main.in MainGhcTTypeable.out diff -b MainGhcTTypeable.out MainGhcTTypeable.ref runhugs -98 +o MainHugsTTypeable.hs Main.in MainHugsTTypeable.out diff -b MainHugsTTypeable.out MainHugsTTypeable.ref ghci -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances MainPosting-040607.hs -v0 Main.in MainPosting-040607.out diff -b MainPosting-040607.out MainPosting-040607.ref ghci -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances MainGhcGeneric2.hs -v0 Main.in MainGhcGeneric2.out diff -b MainGhcGeneric2.out MainGhcGeneric2.ref ghci -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances MainGhcGeneric3.hs -v0 Main.in MainGhcGeneric3.out diff -b MainGhcGeneric3.out MainGhcGeneric3.ref [EMAIL PROTECTED] ~/projects/HList/src -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Frank Sent: Saturday, December 24, 2005 8:46 AM To: haskell@haskell.org Subject: [Haskell] Hlist distribution -- compiler error in TIP I just got the Hlist distribution but could not compile the example files With ghc 6.4 (I use ghci - in eclipse - I did not use ghc with the makefile). I got the following compile time error on module TIP: C:\gisCodev13\HeterogenousList\src/TIP.hs:247:22: Could not deduce (HType2HNat e l n1, HDeleteAtHNat n1 l l'1, HOccurs e (TIP l), HOccurs e2 (TIP l'1)) from the context (HOccurs e1 (TIP l), HType2HNat e1 l n, HDeleteAtHNat n l l', HOccurs e2 (TIP l'), HOccurs e2 (TIP l), HType2HNat e2 l n', HDeleteAtHNat n' l l'', HOccurs e1 (TIP l'')) arising from use of `y' at C:\gisCodev13\HeterogenousList\src/TIP.hs:247:22 Probable fix: add (HType2HNat e l n1, HDeleteAtHNat n1 l l'1, HOccurs e (TIP l), HOccurs e2 (TIP l'1)) to the type signature(s) for `tuple' or add an instance declaration for (HOccurs e (TIP l), HOccurs e2 (TIP l'1)) In the definition of `tuple': tuple (TIP l) = let x = hOccurs (TIP l) l' = hDeleteAtProxy (toProxy x) l y = hOccurs (TIP l') in (x, y) Can anybody quickly see, what is wrong? Andrew U. Frank Professor, Head of Department Geoinformation and Cartography E127 phone: +43 1 588 01 12710 TU Vienna secr. +43 1 588 01 12700 Gusshausstrasse 27-29 fax +43 1 588 01 12799 A-1040 Vienna Austria cellular phone +43 676 41925 72 http://www.geoinfo.tuwien.ac.at/persons/frank/frank.html skype:AndrewUFrank ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Call for papers -- FOAL 2006: Foundations of Aspect-Oriented Languages
FOAL: Foundations of Aspect-Oriented Languages --- CALL FOR PAPERS --- Submission deadline: 25 January 2006 A one day workshop affiliated with AOSD 2006 in Bonn, Germany, on March 21, 2006. Themes and Goals FOAL is a forum for research in foundations of aspect-oriented programming languages. Areas of interest include but are not limited to: - Semantics of aspect-oriented languages - Specification and verification for such languages - Type systems - Static analysis - Theory of testing - Theory of aspect composition - Theory of aspect translation (compilation) and rewriting The workshop aims to foster work in foundations, including formal studies, promote the exchange of ideas, and encourage workers in the semantics and formal methods communities to do research in the area of aspect-oriented programming languages. All theoretical and foundational studies of this topic are welcome. The goals of FOAL are to: - Make progress on the foundations of aspect-oriented programming languages. - Exchange ideas about semantics and formal methods for aspect-oriented programming languages. - Foster interest within the programming language theory and types communities in aspect-oriented programming languages. - Foster interest within the formal methods community in aspect-oriented programming and the problems of reasoning about aspect-oriented programs. Workshop Format The planned workshop format is primarily presentation of papers and group discussion. Talks will come in three categories: long (30 minutes plus 15 minutes of discussion), short (20 minutes plus 5 minutes of discussion) and very short (7 minutes plus 3 minutes of discussion). The very short talks will allow for short presentations of topics for which results are not yet available, perhaps for researchers who are seeking feedback on ideas or seek collaborations. We also plan to ensure sufficient time for discussion of each presentation by limiting the number of long talks and having only a few short talks. Submissions Invitation to the workshop will be based on papers selected by the program committee; those wishing to attend but not having a paper to submit should contact the organizers directly to see if there is sufficient space in the workshop. FOAL solicits full-length, short, and very short papers on all areas of formal foundations of AOP languages. Submissions will be read by the program committee and designated reviewers. Papers will be selected for long, short, and very short presentation at the workshop based on their length, scientific merit, innovation, readability, and relevance. Papers previously published or already being reviewed by another conference are not eligible. Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than their paper length would otherwise command. We will limit the length of paper presentations and the number of papers presented to make sure that there is enough time for discussion. Papers presented at the workshop will be included in a technical report (from Iowa State University). Authors will retain their own copyright to the papers. Publication of papers at other venues will thus remain possible. We will also investigate having a special issue of a journal for revisions of selected papers after the workshop. Authors should note the following details: - Submissions are due no later than 23:00 GMT, Friday, 25 January, 2006. This is a firm deadline. - Authors must indicate whether they wish to be considered for a long, short, or very short presentation. - Papers for long presentations must not exceed 10 pages in length; those for short presentations must not exceed 5 pages in length, and those for very short presentations must not exceed 3 pages in length. - Some papers may not be selected for presentation, and some may be selected for presentation in shorter talks than requested. - We encourage use of the ACM Conference format for submissions, as this will be required for accepted papers. You must add page numbers (which are not part of the standard format) to your submissions, to make adding comments easier. - Submissions are to be sent as PDF (preferred) or postscript attachments in an email to Curtis Clifton, clifton -at- rose-hulman -dot- edu. We will notify the corresponding author of papers that are selected for presentation at the workshop by 10 February 2006. The early registration deadline for AOSD will be 17 February 2006. FOAL attendees must be registered for AOSD. Final versions of papers for the proceedings will be due on 7 March 2006. Important Dates * Submission Deadline 23:00 GMT, 25 January 2006 * Notification of Acceptance 10 February 2006 * AOSD Early Registration Deadline 17 February 2006 * Final Versions of Papers due 7 March 2006 * Workshop 21 March 2006 Program Committee * Mira Mezini (PC Chair) - Darmstadt University of Technology * Jonathan Aldrich -
RE: [Haskell] Re: Records
Good questions. You can't have a polymorphic typecase like `extQ` (show :: Show a = a - String ) because that's not really a *type*case. It is too polymorphic. You can have a polymorphic typecase like `extQ` ( lshow :: [ a ] - String ) because that's covered by the SYB2 paper; you need ext1Q (extQ1, depending on version). With SYB3, the second case is easier; it's just an instance. The first case ... still doesn't work ... this time for reasons of the class system. The type system doesn't allow to write one default instance for the case that a certain constraint is satisfiable (here: Show a) and to have yet another default instance to kick in *otherwise* to the SYB version. It would be great to have typeclass case to deal with this issue. Questions asking for typeclass case pop every now and then. The idea of the example is that you would need to define your own generic show function from scratch. The limitation of SYB1/SYB2 is that you would hit a closed-world-assumption. That's why SYB3! It allows you to add instances to the new generic show, as you go. Because of the lack of typeclass case, you still wouldn't be able to use the normal Prelude show function as default. You can use it instance-per-instance, by adopting each (attractive) show instances to be become instance of the new generic show function. However, you need to clone code because you probably want to re-tie the recursive knot in the new generic function. SYB3 is shipped separately, please use the distribution you pointed to. Simon PJ and I are still undecided regarding the modalities for adding SYB3 to the GHC libraries. Basically, we don't like the idea of having two libraries; SYB3 is more powerful but the combinator types are somewhat more complicated. However, using the separate SYB3 distribution is safe because it comes with TH support and a standalone mini SYB library. Regards, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Johannes Waldmann Sent: Monday, November 28, 2005 7:33 AM To: haskell@haskell.org Subject: [Haskell] Data.Generics question Dear all, in Data.Generics.Text http://cvs.haskell.org/cgi- bin/cvsweb.cgi/fptools/libraries/base/Data/Generics/Text.hs?rev=1.10 I find this nice example gshow = ( \t - ( ++ showConstr (toConstr t) ++ concat (gmapQ ((++) . gshow) t) ++ ) ) `extQ` (show :: String - String) but I couldn't figure out how to use this to declare a useful show instance. I would need something like `extQ` (show :: Show a = a - String ) i. e. use Show instance if available, or `extQ` ( lshow :: [ a ] - String ) i. e. use another function if argument type is a list type BTW: I guess the above is related to http://homepages.cwi.nl/~ralf/syb3/ Do the current (6.4) ghc compiler/libraries correspond to what's in that paper? -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- http://www.imn.htwk-leipzig.de/~waldmann/ --- ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] records proposals list
I certainly agree with Keean. It's just that the given example is a bit misleading. As Bulat observed, the example is about a heterogeneous list, as opposed to a record. But there are of course tons of record examples to be found, if you follow the HList link. Ralf P.S.: The HList paper also has a reasonable related work section, which might hold more information of the kind that Bulat asked for. -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Keean Schupke Sent: Monday, November 21, 2005 7:56 AM To: Bulat Ziganshin Cc: Haskell Cafe Subject: Re: [Haskell-cafe] records proposals list Hi, Haskell already has static records (in H98) Dynamic records are addressed by the HList library, which uses extensions already present in GHC and Hugs (namely Multi-parameter type-classes and function-dependancies). So you can do this now... with reasonable syntax, for example to create an extensible record (some thing .*. (27 :: Int) .*. True .*. HNil) is a statically typed anonymous record. In other words there is no need for any more extensions to GHC or Hugs to implement Records (although having a type-level type-equality constaint would simplify the internal implementation of the library)... For details see the HList paper: http://homepages.cwi.nl/~ralf/HList/ Regards, Keean. Bulat Ziganshin wrote: Hello Haskell, can anyone write at least the list of record proposals for Haskell? or, even better, comment about pros and contras for each proposal? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Type classes and hFoldr from HList
Hi Greg, Since hfoldr is right-associative, I prefer to reorder your list of functions as follows: test = HCons (length::String - Int) (HCons ((+1)::(Int-Int)) (HCons ((*2)::(Int-Int)) HNil)) Note that I also annotated length with its specific type. (If you really wanted to leave things more polymorphic, you would need to engage in TypeCast.) Providing a specific Apply instance for (.) is not necessary, strictly necessary. We could try to exploit the normal function instance for Apply. Let me recall that one here for convenience: instance Apply (x - y) x y where apply f x = f x Let me also recall the hFoldr instances: class HList l = HFoldr f v l r | f v l - r where hFoldr :: f - v - l - r instance HFoldr f v HNil v where hFoldr _ v _ = v instance ( HFoldr f v l r , Apply f (e,r) r' ) = HFoldr f v (HCons e l) r' where hFoldr f v (HCons e l) = apply f (e,hFoldr f v l) To fit in (.), we would flip and uncurry it. So we could try: comp' = hFoldr (uncurry (flip (.))) (id::Int - Int) test This wouldn't work. The trouble is the required polymorphism of the first argument of hFoldr. The type of that argument as such is polymorphic. However, this polymorphism does not survive type class parameterization. You see this by looking at the HCons instance of HFoldr. The different occurrences of f would need to be used at different types. This would only work if the type class parameter f were instantiated by the polymorphic type of (uncurry (flip (.))). (And even then we may need something like TypeCast.) What you can do is define a dedicated *type code* for composition. comp = hFoldr (undefined::Comp) (id::Int - Int) test data Comp instance Apply Comp (x - y,y - z) (x - z) where apply _ (f,g) = g . f Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Greg Buchholz Sent: Sunday, November 06, 2005 7:01 PM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Type classes and hFoldr from HList I was playing around with the HList library from the paper... Strongly typed heterogeneous collections http://homepages.cwi.nl/~ralf/HList/ ...and I thought I'd try to fold the composition function (.) through a heterogeneous list of functions, using hFoldr... {-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} import CommonMain main = print $ comp abc test = HCons ((+1)::(Int-Int)) (HCons ((*2)::(Int-Int)) (HCons length HNil)) comp = hFoldr (.) id test instance Apply (a - b - c - d) (a, b) (c - d) where apply f (a,b) = f a b ...but it fails with the following type error... ]Compiling Main ( compose.hs, interpreted ) ] ]compose.hs:10:7: ]No instances for (Apply ((b - c) - (a - b) - a - c) ](Int - Int, r) ]([Char] - a3), ] Apply ((b - c) - (a - b) - a - c) (Int - Int, r1) r, ] Apply ((b - c) - (a - b) - a - c) ([a2] - Int, a1 -a1) r1) ] arising from use of `hFoldr' at compose.hs:10:7-12 ]Probable fix: ] add an instance declaration for (Apply ((b - c) - (a - b) - a - c) ] (Int - Int, r) ] ([Char] - a3), ] Apply ((b - c) - (a - b) - a - c) ](Int - Int, r1) r, ] Apply ((b - c) - (a - b) - a - c) ]([a2] - Int, a1 - a1) r1) ]In the definition of `comp': comp = hFoldr (.) id test ...Anyway, I couldn't quite tell whether I was using hFoldr incorrectly, or if I needed to have more constraints placed on the construction of test, or if needed some sort of type-level function that resolves... Apply ((b - c) - (a - b) - a - c) ...into (a - c), or something else altogether. I figured someone might be able to help point me in the right direction. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] handling rank 2 types
In a type system like MLF, your original code may type check. Let's do an experiment. We replace the IO monad by the Id(entity) monad. We actually replace the Id newtype also to become true type-level identity. So we get: -- -- This is like your 2nd say unchecked... sample -- fooBar :: [v] - Empty fooBar l = Empty (map no l) where no :: a - a' no x = error element found But the problem is not about a higher-rank type occurring with a type constructor, as you guess. It is rather about functions with classic rank-1 types. To see this, insert $ for the application of Empty: fooBar :: [v] - Empty fooBar l = Empty $ (map no l) where no :: a - a' no x = error element found You get the same type error as for the original monadic code. What you could do is define a suitably typed application operator (likewise, a suitably typed liftM). (With MLF the various types would be admitted by a more general type.) In the non-monadic example, we need: -- Use app instead of ($) app :: ((forall a. [a]) - c) - (forall b. [b]) - c app f x = f x BTW, what operations are we supposed to perform on the content of Empty; what's the real purpose for introducing this independent type variable a'? Parametric polymorphism seems to suggest that we can't do much. You can observe the length of the list. That's it, more or less. Why not store the length directly rather than having this superficially polymorphic list? I am a little bit lost. You wonder how you can generally solve this sort of problem? - You seem to spot the wrapping approach: wrap foralls and unpack at application time. This makes particularly sense for polymorphic *functions*. - The other approach is to use consistently rank-2 combinators. I probably don't get what you try to do. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Andrew Pimlott Sent: Thursday, November 03, 2005 8:35 PM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] handling rank 2 types I am trying to use a rank 2 type to enforce a condition on a data structure. For the purpose of this message, I am trying to ensure that a list is empty (ignoring the possibility of bottom elements): {-# OPTIONS -fglasgow-exts #-} import Control.Monad newtype Empty = Empty (forall a. [a]) I want a function listToEmpty :: [v] - IO Empty listToEmpty l = liftM Empty (mapM no l) where no :: a - IO a' no x = fail element found But this gives a less polymorphic error. I think the problem is that ghc will not instantiate the a' in IO a' as a higher-rank type because it occurs within a type contructor. I believe this is the restriction referred to at the end of 7.4.9[1]. If I instead write uncheckedListToEmpty :: [v] - Empty uncheckedListToEmpty l = Empty (map no l) where no :: a - a' no x = error element found it compiles, because v' can be instantiated as forall v. Rule v, and even pass through map with the higher-rank type. Is there any way to make ghc accept the first definition? I found this workaround: newtype Any = Any { unAny :: forall a. a } listToEmptyAny :: [v] - IO Empty listToEmptyAny l = liftM (\l - Empty (map unAny l)) (mapM no l) where no :: a - IO Any no x = fail element found But needing a newtype wrapper Empty was bad enough; do I really need one for every intermediate result (that is inside another type constructor) as well? I could probably define a generic family of wrappers newtype Forall = Forall (forall a. a) newtype Forall1 c1 = Forall1 (forall a. c1 a) newtype Forall2 c1 c2 = Forall2 (forall a. c1 c2 a) ... But I would still have to use them everywhere. Any other tricks? Andrew [1] http://haskell.org/ghc/docs/latest/html/users_guide/type- extensions.html#universal-quantification ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: Instances That Ignore Type Constraints? (HList-related)
Yeah, I was also thinking of impredicative types and that they would make this problem go away. First of all, we may need to wait a while for such types to become available in Haskell, but Daan has good stuff at avail. Also, for clarity, let me just point out that this is really about an *interaction* of impredicativeness *and* type classes. Hence, I really think that an argument in favor of impredicative types is slightly overrated unless a Haskell approach to impredicativeness is fully conclusive for the type-class story. The following queries make it clear: Prelude null [fromEnum] interactive:1:6: Ambiguous type variable `a' in the constraint: `Enum a' arising from use of `fromEnum' at interactive:1:6-13 Probable fix: add a type signature that fixes these type variable(s) Prelude null [id] False More importantly, I need more input to fully endorse the appropriateness of impredicative types in this sort of context. That is, the question is ... what does it *mean* to wrap (or to box or to cartoon) an expression with non-escaping type variables that locally occur in type-class constraints? GHC/Haskell, as of today: - it means nothing; type error. Some sort of impredicative type: - it means universal quantification Potentially elsewhere: - it means existential quantification In Ghc with incoherent instances: - see above; except that the instance is actually selected. In addition to this scary diversity, all the three last choices are bogus in some sense because the quantified variables are totally inaccessible; so why would a type system honor such potentially accidental opaqueness. In summary, this makes me conclude that null [fromEnum] is just a really loose question to ask, which is perhaps just better rejected by a strong type system, no? Please, prove that I am wrong. :-) Ralf Oleg wrote: When GHC does implement MLF and start explicitly supporting impredicative types, the problem would be fixed indeed... Currently, the only way to achieve the same effect is to do this manually: newtype W = W (forall a. (Enum a) = a - Int) *Main null [W fromEnum] False Perhaps indeed we should move to Cafe... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell] Instances That Ignore Type Constraints? (HList-related)
Hi, 'isBoxed (Carton func)' fails because there is no way whatsoever that any expression context will disambiguate the x y type variables of func's type. That is, the type of `isBoxed (Box func)` does not expose x (and y -- the latter being irrelevant because of the fundep); so there is no way that the type system could ever figure out which x (and y) was meant; hence overloading will never ever get resolved (check out the hugs type error, which tells you exactly that). One could argue in favor of incoherent choice of instances. (I don't!) Say, if you had: {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-incoherent-instances #-} instance Func x x -- or some other generic instance It will work fine: ghci isBoxed (Carton func) HFalse However, why would you want to wrap such a function anyhow, if you are not going to use it? :-) Perhaps, this is a case of superficial, say unintended polymorphism. If you *really* wanted to box (or to carton) a polymorphic type-class bounded function, then you may need to do something like this: data WFunc = WFunc (forall x y. Func x y = (x - y)) hugs-or-ghci isBoxed (Carton (WFunc func)) HFalse This works fine ... but this is probably *not* what you wanted in the first place. Also, this technique is extremely limiting because now you would need to fabricate wrappers like WFunc for each new polymorphic expression (when the constraints or the type differ). I am keen to hear more about your problem, and to help accordingly. (Haskell-café?) Regards, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Jared Warren Sent: Wednesday, October 26, 2005 7:01 PM To: Haskell Mailing List Subject: [Haskell] Instances That Ignore Type Constraints? (HList-related) data Box x = Box x data Carton x = Carton x class Func x y | x - y where func :: x - y class IsBoxed f b | f - b where isBoxed :: f - b instance IsBoxed (Box x) HTrue where isBoxed _ = hTrue instance IsBoxed (Carton x) HFalse where isBoxed _ = hFalse `isBoxed (Box func)` fails in GHC with Ambiguous type variables `x', `y' in the constraint: `Func x y' arising from use of `func' ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] getArgs, maxBound, float division: pure functions?
Just for the record, Cobol has a long history of specifying local rounding options. More recently, the options for rounding are elaborated in the context of adding standard arithmetic. http://www.cobolportal.com/j4/files/05-0152.doc Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Bjorn Lisper [...] He was very careful to give the language a good design also regarding floating-point computations. His design choice, as regards rounding, was to allow the compiler to choose rounding mode by default (thus allowing more freedom for optimization), while providing a set of special arithmetic operators, with specified rounding modes, to use when more explicit control is needed. He also proposed a special construct letctrl ... in e, where the ... are a list of directives telling how to interpret and evaluate the expression e. One possible directive is RoundingMode = ... to set the rounding mode locally in e. Other directives control, for instance, whether optimizations like x*0.0 - 0.0 are allowed in e, whether to force strict evaluation of all subexpressions (so optimizations cannot affect exceptions), to set allowed miminum accuracy, etc. The language has exception handling (including a handle construct to catch exceptions), which also takes care of floating-point exceptions. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] Object-Orientation and Haskell
Define a type A such that for any type B you can define up :: B - A down :: A - Maybe B such that down . up = Just You can do this quite easily in Java or C++, mutatis mutandis. You can't do this in Haskell, I don't think. You can't actually do this in O'Haskell either, it seems the O' essentially amounts to syntactic sugar. You can't even do this in OCaml. However, in OOHaskell you can. From the TOC of the OOHaskell paper http://homepages.cwi.nl/~ralf/OOHaskell/ 5.4 Casts based on dynamics 50 5.5 Casts based on unions 51 The second technique may add something to this discussion here. We use a sort of intersection-type encoding (also reminiscent of TICs). Thanks, Ralf ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] reflection/metadata in Haskell?
I would rather argue that: - Template Haskell approx. *compile-time* reflection - Scrap your boilerplate II (ICFP 2004) approx. *run-time* reflection - Generic Haskell is effectively a Haskell generator Ralf P.S.: Another way to get *compile-time* reflection in Haskell is of course type-level programming as pioneered by McBride and Hallgreen ... -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Mads Lindstrøm Sent: Wednesday, September 21, 2005 11:40 AM To: haskell@haskell.org Subject: Re: [Haskell] reflection/metadata in Haskell? ... I do not know of any Java-like reflection capabilities in Haskell. However, Scrap Your Boilerplate (search google) and Generic Haskell can do a lot of the same stuff reflection can do in Java. Think of it as compile-time reflection. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] generics question, logical variables
Hi Frederik, [I call this the dreadful lack of kind polymorphism strikes back :-)] I put SPJ on cc; perhaps he can suggest a way to improve in this area. Based on input, I could try to work on this issue in the not so remote future. Let me briefly recapitulate. My recollection is that deriving works for Typeable, Tyepable1, ..., if all type parameters are of type kind *. Whenever you can derive a Typeablen instance with n 0, you can instead ask for Typeable to be derived. The reason why you cannot get both a Typeable and say a Typeable42 instance is that there are generic instances for getting an n-1 instance from the n instance. However, this is also precisely the reason why you don't want them both. That is, you get everything you can ask for, if you have the n instance for the actual arity of the type constructor in question. (Getting a smaller n or no n just means that you limit polymorphic type case.) Recall that you *may* need a n0 instance if you want to do polymorphic type case according to the SYB2 paper. As long as you are fine with monomorphic generic function extension, the plain Typeable instance should be fine. However, the real limitation is here, *indeed*, as said, that GHC does not derive Typeable[1|2|...] for parameter kinds other than *. This was the reason that I had to hand-code some Typeable instances in your original example. Let us also be honest about another limitation of the current deriving code. deriving Data gives you Data instances that do *not* support polymorphic type case. That is the following code prints 0, 1, 0 whereas you may expect 0, 1, 2. newtype Foo x = Foo x deriving (Typeable, Data) f :: Data a = a - Int f = const 0 `ext1Q` (\(_::Maybe x) - 1) `ext1Q` (\(_::Foo y) - 2) main = do print $ f True print $ f (Just True) print $ f (Foo (Just True)) This is the reason that I had to handcode some Data instances in your original example, which wasn't hard BTW. We thought that these two limitations were Ok since we didn't expect people to write many polymorphic datatype constructors on which SYB should work. Sounds like a feature request. Now I wonder how much work it is to improve the situation. We need to make the GHC deriving code a bit more kind-aware. I guess we are still not at the point where we want to add kind polymorphism to Haskell? Would be a nice topic for future work on SYB. Clearly, the GH folks have done splendid work in this area. Getting full-blown kind polymorphism in normal Haskell though seems to be less of a topic, simply because we do not have many scenarios around that would *really* require it. Does anyone want to speak up and mention scenarios that would benefit from kind polymorphism? (In Haskell, we are likely to see kind polymorphism, if at all, in the form of type classes whose type parameters can be of different, perhaps of all kinds.) Frederik, for the time being I propose to look into TH code for deriving Tyepable/Data instances and to make it fit for your purposes. There are several versions of Ulf Norell's code around. You may also use SYB3 with the TH code that readily comes with it. Thanks for bringing this up. Regards, Ralf -Original Message- From: Frederik Eaton [mailto:[EMAIL PROTECTED] Sent: Sunday, September 18, 2005 7:50 PM To: Ralf Lammel Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] generics question, logical variables Hi Ralf, I'm revisiting this project and just have another question. The story seems to be that GHC cannot derive Typeable1, or Typeable when Typeable1 is available - so anyone who wants to use ext1Q must define special instances for all of the datatypes they use, is this correct? Will this change soon? Aside from that, your 'idify' in PseudoFmap2 certainly seems to have the correct type for this application. However, the absence of automatic derivation is somewhat of an impediment. Thanks for your help. Frederik On Tue, Aug 30, 2005 at 02:25:08PM -0700, Ralf Lammel wrote: Frederik, As for your code example, it looks very interesting, but are you saying that this could turn into an extension of the Data.Generics library, or that this is something I could be implementing in terms of what's already there? The posted code works with GHC 6.4 (SYB2) intentionally and actually. I have attached another attempt (again GHC 6.4, based on SYB2) which might be more useful for your purposes, and it may be useful in general, in fact. What I defined this time is a certainty-improving function: idify :: (Typeable1 f, Monad m, Data (a f), Data (a Id)) = (forall a. f a - m a) - a f - m (a Id) That is, the function idify get takes a value whose type is parameterized in a type constructor f (such as Maybe or IORef), and the function attempts to establish Id instead of f on the basis of the function argument get. What is the 'a' parameter for in force? force
[Haskell] OOHaskell -- major release of report and library
An extended technical report has been released at: TR software: http://homepages.cwi.nl/~ralf/OOHaskell/ TR: http://arxiv.org/abs/cs.PL/0509027 Haskell's overlooked object system 10 September 2005, 79 pages by O. Kiselyov (FNMOC, Monterey, CA, USA) and R. Laemmel (Microsoft Corp., WA, USA) Some recently added topics: - Many Haskell 98 encodings - Safe value recursion - Safe downcasts - Safe co-variant method arguments - Nominal subtyping - Iso-recursive object types - With and depth subtyping The report describes and classifies all principled, to our best knowledge, object encodings in Haskell98, with and without common extensions. On the one hand, this report covers many advanced topics, as to make it interesting for programming language researchers. On the other hand, the report is detailed and lightweight enough to be useful as an OO-FP tutorial. Regards, Oleg and Ralf ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] Language Workbenches - the Haskell solution?
Yoann, Thanks for your comments. Yoann wrote: I dont think XML is a good idea for files that are managed/edited by humans. I think the users prefer simpler files with a custom syntax, and the user is the king. I dont mind, but when you say user do you mean application configuration admin or plain application user. The former may know/like/dislike PL syntax, the latter may not like *anything* but very simple and foolproof formats or GUI-based configuration. There is no reason to believe that the latter wants to feel like programming in Haskell, Java, at least not in the universe I live in or that I observe. Yoann wrote: Of course the job of the programmer is easier when the file is coded in XML, This is unrelated to what I said. Perhaps my wording wasnt clear enough. I was trying to refer to the software life cycle and tool support as a whole. Doing software re-engineering for configurations that are formulated in a Turing-complete language is no fun. This is quite similar to the known issues with macros, when used for configuration; you may want to read about software asbestos here: http://homepages.cwi.nl/~ralf/am/ Yoann wrote: I am a programmer and personally I dont want to code my Haskell code in XML I didnt propose *that*. Anyway, picking up the new subject that you introduced accidentally, let me reply: you are not alone: most programmers dont like to code their PL code in XML. (As an aside, XML is used even for coding these days, just in case you dont know: check out some widely used AOP language extensions for Java. I am not saying whether I like this or not.) Yoann wrote: so I presume it is the same for the user with configuration files. So you presume that a user of application XYZ prefers to configure his/her application in the syntax of the underlying implementation language, supposing there is just one? Thats a very interesting presumption. Have you any data to substantiate your presumption, or is that a prediction for the future? Yoann wrote: if your programming langage is lisp in which case parsing the configuration file isjust a call to read. Sure! Sounds a bit like comparing apples and oranges. I can also parse my configuration file to Data.Tree String in Haskell, or something similarly weakly typed. Then parsing is just a call to read, too. (Lisp really doesnt score here.) So whats the point? I guess we wont be happy with that Haskell solution, or at least we would like to see whether we can score with Haskell in some way. Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Language Workbenches - the Haskell solution?
Hi Yoel, This looks like fun. Just some general comments: - One should try to *also* provide a simple solution. Here I would pick a solution that doesn't need a lot of explanation (of Haskell and the solution) and a lot of defense to score with it. - As a second step, one should identify a sweet spot upfront. The sweet spot could indeed be to get some extra static typing; some extra DSL checks; some increased declarativeness. (Or all of it.) To this end, I would study the DSL problem at hand, and not so much yet think of Haskell encoding. You can only score with Haskell, if there is something to be scored with in the problem at hand. - Now one can explore the identified sweet spot by trying to put strong Haskell features such as hs-plugins or Data.Generics or Data.Dynamic or phantoms or all of them or something else to work. - I haven't looked at the discussion, but a sophisticated Java solution could also try to score with dynamic class loading, reflection, perhaps even with compile-time reflection a la OpenJava. One would need to be prepared to cope with that ;-) - XML wasn't mentioned in your message. I wonder whether they discuss it in the actual thread. (Yes, you might be saying XML is not the same language as you are programming in, but it so easy to process XML in many languages, and one uses XSD for the DSL syntax). In fact, in Haskell I would strongly consider using HaXML or similar technology for non-trivial configuration problems. XML makes configuration also more portable. In reality, I don't see much value in using the programming language syntax for representing the configuration information. This makes it only harder to process those configurations with other tools. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Yoel Jacobsen Sent: Thursday, September 08, 2005 11:41 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Language Workbenches - the Haskell solution? I'm trying to create an _elegant_ solution in Haskell. ... Further, what is the type of the parser? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: [Haskell] Monadification as a refactoring [was: Mixing monadicand non-monadic functions]
Frederik, [I am trying to drag this voluminous thread to cafe.] Jeremy Gibbons mentioned Martin Erwig and Deling Ren's paper on monadification. Very useful, indeed -- also with regard to the question you seem to ponder about; also see here for an early take on monadification, if you like http://homepages.cwi.nl/~ralf/sfp99/ and more recently, an interesting use case for it: http://homepages.cwi.nl/~ralf/foal03/ I disagree with you: Monadification transformations are certainly reversible. I *do* realize that you were not talking about plain reversibility but rather a refactorization should have an inverse which commutes with simple edits. Let's talk about plain reversibility first. So you go from a non-monadic program to a monadic program. What monad do you choose initially? You use the identity monad, at least conceptually. (Making the monadic parametric, if intended, can be seen as an extra generalization step. To use such a generalized program, you would still need to commit to a specific monad eventually at a higher level of the program. So for simplicity it makes sense to start from a monadified program that uses the identity monad. A single monadification refactoring is not enough anyhow, if you care about monad-related program edits in a broader scope. You would also need extra refactorings and refinements for extending and reducing the monad through symbolic monad transformations and a few others, I presume.) Inlining the identity monad operations plus some bits of beta reduction get you back to the original program. (There are some subtle technical issues. For instance, getting rid of a monad, even if it is not used through actions, may still be difficult due to strictness/bottom lifting issues. See such details in Martin's paper.) How do go beyond plain reversibility for monadification? Your examples of refactorings were not fair. They did not admit that undoing refactorings *after program edits* is a problem for *many* established refactorings. Monadification is not really special in so far. (It is perhaps special in so far that it is generally a rather involved refactoring, compared to extract/inline method.) You mention (i) extract function followed by (ii) edit function followed by (iii) inline function. (iii) is the inverse refactoring for (i). Now try this (iii), (ii') edit inlined code, (i). How do you know what to extract in the last step? How do you know where to extract (if you changed only n out of m inlining locations)? AND SO ON. These are all not insurmountable problems but they are quite similar to the challenges you run into once you want to inverse monadification. *As long as we keep the notion of edits vague, as you did, it shouldn't be surprising that reversibility after edits is not clear either.* Obviously, some edits can be handled by de-monadification. As long as the edits do not start to commit to monadic style by means of engaging into a specific non-identity monad *and* using monadic actions, then it is safe to exclude monadic style again. (Making this precise and really *safe* is difficult enough.) But even once you start to use commit/engage, after monadification, there are ways to eliminate it again on the basis of special treatments per monad. (Think of refactorings that extract or inline monadic style for specific monads; for instance state passing through extra argument and result components.) Also, you may reduce the amount of monadic style. HaRe efforts are addressing some concepts like this, I guess. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Frederik Eaton Sent: Saturday, September 10, 2005 4:25 PM To: Claus Reinke Cc: haskell@haskell.org Subject: Re: [Haskell] Monadification as a refactoring [was: Mixing monadicand non-monadic functions] On Sat, Sep 10, 2005 at 12:55:15AM +0100, Claus Reinke wrote: life is funny, isn't it? so many people so eagerly lazily, in my case discussing conversion between non-monadic and monadic code, I'm trying to discuss a new syntax, not code transformations. I agree that the two are related. I'm interested in the latter, but I don't understand it very well. I think of refactoring as an operation that takes source code to source code, i.e. unlike most operations done on source code, refactoring produces output which is meant to be edited by humans. Is this correct? But if it is, doesn't it mean that one would like refactorizations to have some ill-defined reversibility property: a refactorization should have an inverse which commutes with simple edits For instance, if I (a) rename a variable, and then (b) introduce a new reference to the renamed variable somewhere, I can later decide to change the name back, reverting (a), without losing the work I did in the meantime in (b). I can do this by applying another rename operation, which will also affect the new reference. Or, if I (a) take a bit of code and remove it to
RE: [Haskell-cafe] generics question, logical variables
Frederik, Thanks for the challenge. I didn't get some of the bits about your application scenario though. (What did you mean by the type Pred? Why a list in the result of solve? How did you model typed logical variables? With GADTs, phantoms? ... Perhaps send more code, if you want to discuss this topic more.) So I hope that the attached make sense to you. I do believe so. I have coded a function that converts a term t Maybe a to a term t Id a, where I assume that: - t is the Haskell type that may involve Maybe/Id spots. - Maybe/Id spots for variables are wrapped in a dedicated datatype Spot, - a is the type of the term with regard to some custom type system. - The custom type system is model as a class Term. Here is the conversion function: force :: ( Data (t Maybe a) , Data (t Id a) , Term t Maybe a , Term t Id a ) = t Maybe a - t Id a force = fromJust . tree2data . data2tree This example assumes that all Maybe spots are actually Just values. Clearly, you can do some error handling in case this cannot be assumed. You could also make the Maybe-to-Id conversion part of the traversal that resolves holes. This is not the challenge, the challenge was indeed to traverse over a term and to get the types right when replacing subterms of type Maybe x by subterms of type Id x. The actual type conversion relies on going through the universal Tree datatype. We use Tree Constr as the type of an intermediate value. (We could also use Tree String but this would be more inefficient. BTW, we take here dependency on the invariant that constructors in Constr are polymorphic. So SYB's reflection is nicely generic; compare this with Java.) When encountering spots during trealization, they are converted from Maybies to Ids. Then, a subsequent de-trealization can do its work without any ado. The deep trealization solves the problem of exposing these type changes to the type of gfoldl. (Amazingly, one might say that the type of gfoldl is just not general enough!) I guess I should admit that: - We temporally defeat strong typing. - We make the assumption that all occurrences of Spot are to be converted. - That is, we don't quite track the type parameter for Maybe vs. Id. - This is a bit inefficient because of going through Tree Constr. So I am willing to summarize that this is potentially a sort of a (cool) hack. Code attached. Ralf P.S.: The extension you propose seems to be a major one. Perhaps you could look into the TH code for SYB3 (ICFP 2005) to see whether this can be automated. This sort of discussion calls for kind polymorphism once again. -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Frederik Eaton Sent: Sunday, August 28, 2005 9:36 PM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] generics question, logical variables Hi all, I'm trying to write something like a generic fmap, or a generic natural transformation. The application is this. I have a typed logical variable library which produces arbitrary terms with values of type Var a, which are references to a value of type Maybe a, and I want to write a solve function which replaces these values with instantiated versions of type Id a where newtype Id a = Id a . Furthermore I want this to be reflected in the type of the generic term: solve :: Pred (t Var) - [t Id] so if I have a type like data Entry k = Entry (k String) (k Int) then I can write some constraint equation with values of type Entry Var, and get back values of type Entry Id - in other words, objects where the unknowns are statically guaranteed to have been filled in. I looked at the generics library. I may be mistaken, but it seems that it doesn't have what I need to do this. The problem isn't the mapping, it's creating a new type which is parameterized by another type. The only options for creating new types are variations on fromConstr :: Data a = Constr - a but what is needed is something like fromConstr1 :: Data1 a = Constr1 - a b With something like that it should be possible to define: gmapT1 :: (forall b . Data1 b = b l - b m) - a l - a m Does this make sense? Here I would be treating all instances of Data as possibly degenerate instances of Data1 (which just might not depend on the type variable). If it seems like a good idea, I would be interested in helping out with the implementation. Frederik -- http://ofb.net/~frederik/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe PseudoFmap.hs Description: PseudoFmap.hs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: [Haskell] pros and cons of static typing andside effects ?
I don't even want this feature. :-) The point being that datatype declarations, *as such*, are explicit anyhow. Why bother about the explicit quantifiers then? Of course, in a language with inferred datatypes I would mind. That's an interesting question! I also wouldn't (yet?!) support this feature request because we will still confuse beginners, but that's just my feeling. Ralf -Original Message- From: Stefan Holdermans [mailto:[EMAIL PROTECTED] Sent: Tuesday, August 16, 2005 11:48 PM To: Ralf Lammel Cc: haskell-cafe@haskell.org; Benjamin Franksen Subject: Re: [Haskell-cafe] Re: [Haskell] pros and cons of static typing andside effects ? Ralf, Technically this is trivial it seems. I think that some people consider this proposal a problem because typos (misspelled type parameters) immediately lead to the accidental exploration of a more advanced type-system feature and correspondingly more involved error messages. Of course, the type checker could perhaps consider adding Did you really mean to ...?. Well, okay, but as soon as the type checker starts to asking these questions, I would immediately start adding the explicit quantifiers, just to get rid of those annoying warning messages. ;) So one would we also need to be able to control the behaviour of the type checker with respect to these warnings by means of a compiler flag like fno-warn-on-implicit-existential-quantification. All of this is, of course, still trivial. :) Have we thought about it enough to make it a feature request? Regards, Stefan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: [Haskell] pros and cons of static typing andside effects ?
Technically this is trivial it seems. I think that some people consider this proposal a problem because typos (misspelled type parameters) immediately lead to the accidental exploration of a more advanced type-system feature and correspondingly more involved error messages. Of course, the type checker could perhaps consider adding Did you really mean to ...?. Ralf I once read a paper about type classes and existentials (can't remember exact title or author, was it Läufer?) where the proposal was to make existential quantification implicit (just as the universal one is in Haskell98). That is, any type variable that appears on the rhs of a data type, but not on the lhs, is implicitly existentially quantified, as in data XWrap = Show a = XWrap a I always thought this was a pretty nice idea. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: Deriving Typeable instances
(I agree with the two Simons; just want to throw in a few more considerations.) Just curious ... What's the use case, Frank? (It is probably related to debugging or assertion checking; do you have code details that you want to share?) Do you *really* want to do type-case on those multi-arity parametric types in the sense that you would care about keeping n, n-1, n-2, ..., 1 type positions polymorphic when casting? If you don't, then monomorphic instances of Typeable would be fine. And they are much easier to generate, indeed. (Typeable.h in the Data/include dir (ghc cvs) could be of help to solve the problem before GHC catches up.) It's perhaps useful to recall that the arity-sensitive Typeable business was introduced for the purpose of polymorphic type-case in the context of generic programming with SYB1 and 2 (a bit less at level 3) BTW, for the ICFP 2005 style of SYB (level 3), Typeable instances may be entirely avoidable, depending on programming style and scenario. All the best, Ralf (Once again, sounds like kind-polymorphism would simplify the implementation and the use of Haskell.) -Original Message- From: Simon Peyton-Jones Sent: Wednesday, August 10, 2005 3:32 AM To: Simon Marlow; 'Frank Huch'; 'glasgow-haskell-bugs@haskell.org' Cc: Ralf Lammel Subject: RE: Deriving Typeable instances Yes, you could I suppose. But then there'd be a different peculiar change in behaviour at arity 7. I'm not sure that'd be an advantage. Simon | -Original Message- | From: Simon Marlow | Sent: 10 August 2005 10:58 | To: Simon Peyton-Jones; Frank Huch; glasgow-haskell-bugs@haskell.org | Subject: RE: Deriving Typeable instances | | On 09 August 2005 17:16, Simon Peyton-Jones wrote: | | I'm not against this, although you can work around the problem by | adding a library that defines the missing type classes (Typeable8, | Typeable9 etc), and making your compiler generate the instance | itself. There is nothing magic about 'deriving'; it's just | convenient. | | If the arity is 7, couldn't we just generate a Typeable instance, rather than the TypeableN instance? | It would mean you wouldn't get the benefits of TypeableN, but at least you'd have Typeable. | | Cheers, | Simon ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: [Haskell-cafe] Problem type checking class-method implementation
Stefan, the problem can be spotted in the following erased version of your program. data Identity a instance Monad Identity class (Monad m) = IsItem m i where processItem :: i - m () class (Monad m) = IsProcessor p m | m - p where process :: (IsItem m i) = i - m () newtype Item m = Item {processItemImpl :: m ()} newtype ProcessorT p m a = ProcessorT {runProcessorT :: m a} instance (Monad m) = Monad (ProcessorT p m) instance (Monad m) = IsProcessor p (ProcessorT p m) newtype Processor p a = Processor {unwrap :: ProcessorT p Identity a} instance Monad (Processor p) where castItem :: (IsItem (Processor p) i) = i - Item (ProcessorT p Identity) castItem = undefined instance IsProcessor p (Processor p) where process = Processor . process . castItem Recall the type error: Could not deduce (IsItem (Processor p1) i) from the context (IsProcessor p (Processor p), Monad (Processor p), IsItem (Processor p) i) The problem is basically in here: instance IsProcessor p (Processor p) where process = Processor . process . castItem By specializing function signatures according to the instance head, and by applying type checking constraints for functional composition, we get these types: Processor :: ProcessorT p Identity () - Processor p () process :: process :: ( IsProcessor p (ProcessorT p Identity) , IsItem (ProcessorT p1 Identity) () ) = Item (ProcessorT p1 Identity) - ProcessorT p Identity () castItem :: (IsItem (Processor p1) i) = i - Item (ProcessorT p1 Identity) The problem is the type-scheme polymorphic result type of castItem which is consumed by a type-variable polymorphic but type-class bounded argument type of process. The constraint of this application process, i.e., IsItem (Processor p1) i is the one GHC asks for. (Do the hugs test :-)) Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Stefan Holdermans Sent: Wednesday, August 03, 2005 1:01 AM To: haskell-cafe Subject: [Haskell-cafe] Problem type checking class-method implementation Dear Haskellers, Yesterday I stumbled upon a problem type checking a program involving multi-parameter type classes. GHC rejected the program; still, I was not immediately convinced it contained a type error. Having given it some more thoughts, I start to suspect that the type checker is in err and that the program is well-typed after all. But, well, I might be overlooking something obvious... I have reduced my code to a small but hopelessly contrived example program exposing the problem. Please hang on. Because we employ multi-parameter type classes, we need the Glasgow extensions: {-# OPTIONS -fglasgow-exts #-} Let's start easy and define the identity monad: newtype Identity a = Identity {runIdentity :: a} instance Monad Identity where return = Identity Identity a = f = f a Then, let's introduce the foundations for the (contrived) example: class (Monad m) = IsItem m i where processItem :: i - m () class (Monad m) = IsProcessor p m | m - p where process :: (IsItem m i) = i - m () -- ...some more methods, possibly involving p... So, an item is something that can be processed within the context of a certain monad, and a processor is something that can process an item of an appropriate type. Note the functional dependency from m to p: a processor type m uniquely determines the type of the processing context p. Before we move on, consider this canonical item type, which is just a one-field record representing an implementation of the IsItem class: newtype Item m = Item {processItemImpl :: m ()} The corresponding instance declaration is obvious: instance (Monad m) = IsItem m (Item m) where processItem = processItemImpl Furthermore values of every type that is an instance of IsItem can be converted to corresponding Item values: toItem :: (IsItem m i) = i - Item m toItem = Item . processItem Please stick with me, for we are now going to implement a monad transformer for processors (which, for this example, is really just the identity monad transformer): newtype ProcessorT p m a = ProcessorT {runProcessorT :: m a} instance (Monad m) = Monad (ProcessorT p m) where return = ProcessorT . return ProcessorT m = f = ProcessorT (m = runProcessorT . f) instance (Monad m) = IsProcessor p (ProcessorT p m) where process = processItem Then, finally, we use this transformer to derive a processor monad: newtype Processor p a = Processor {unwrap :: ProcessorT p Identity a} runProcessor :: Processor p a - a runProcessor = runIdentity . runProcessorT . unwrap So, we just make sure that Processor is a monad: instance Monad (Processor p) where return
RE: [Haskell-cafe] Proposal: deriving ShallowEq?
Ben, thanks for your clever questions. Let's look at a little GHC 6.4 demo. {-# OPTIONS -fglasgow-exts #-} import Data.Generics main = do print $ toConstr () == toConstr () print $ toConstr (5::Int) == toConstr () print $ toConstr (\(x::Int) - x) == toConstr () print $ id `shallowEq` (id::Int - Int) shallowEq :: Data a = a - a - Bool shallowEq x y = toConstr x == toConstr y This gives: *Main main True False *** Exception: toConstr Some observations: a) We need to say what sort of Num this 5 is because otherwise instance selection will not know how to obtain the constructor for 5. In this sense, SYB is not different from normal type-class-based programming. Well, modulo default declarations; http://www.haskell.org/tutorial/numbers.html So this works (because of a default declaration) *Main show 5 == show () False This one doesn't because there is no default declaration: *Main toConstr 5 == toConstr () interactive:1:0: Ambiguous type variable `a' in the constraints: ... b) You are right. An independently polymorhic shallowEq is more expressive since it allows us to compare the top-level constructors of different specializations of the same type, e.g., Just Char vs. Just String. shallowEq' :: (Data a, Data b) = a - b - Bool shallowEq' x y = toConstr x == toConstr y You also spotted the issue that shallowEq' cannot operate on data of types a and b where either of these is a type scheme. The reason for that is that the instances of Data (and Typeable) involve constraints for the types of the children. As long as these children types are not fixed, toConstr cannot be computed since instance selection cannot be completed. In general, this is a good idea because of the types of gfoldl (and the gmap derivates), but for exercises like shallow equality this is in the way. I don't have a good solution to offer. (I don't see either that this is a show stopper in practice.) We may think of splitting up the API as to define several more precise classes ... c) Just for the record, SYB's toConstr throws for function types. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Ben Lippmeier Sent: Tuesday, July 19, 2005 8:56 PM Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Proposal: deriving ShallowEq? Ralf Lammel wrote: As Bulat points out, the GHC primitive dataToTag# indeed nicely solves the problem. Ben, just for completeness' sake; with SYB, you get such reflective information too (and others): shallowEq :: Data a = a - a - Bool shallowEq x y = toConstr x == toConstr y (dataToTag# returns Int, while toConstr comprises other things like the constructor name.) Ralf, Yes, I ended up using the propper SYB approach instead, though I have noticed that the reflection data types Constr and DataRep make no mention of type variables or functions. For example, this works fine: getTag (Just 5) ==# getTag (Just{}) getTag (Just (\x - x)) ==# getTag (Just{}) But this does not toConstr (Just 5) == toConstr (Just{}) Ambiguous type variables. toConstr (Just (\x - x)) == toConstr (Just{}) No instance for Data (t - t) I appreciate the reasons why this is so, though I think it's interesting to see the practical consequences. A toConstr version of shallowEq works ok so long as you provide a type signature to constrain both arguments to be the same type, and one of them is always fully constructed - which is fine for me at the moment. Ben. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Proposal: deriving ShallowEq?
As Bulat points out, the GHC primitive dataToTag# indeed nicely solves the problem. Ben, just for completeness' sake; with SYB, you get such reflective information too (and others): shallowEq :: Data a = a - a - Bool shallowEq x y = toConstr x == toConstr y (dataToTag# returns Int, while toConstr comprises other things like the constructor name.) Regards, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Bulat Ziganshin Sent: Tuesday, July 19, 2005 1:18 AM To: Ben Lippmeier Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Proposal: deriving ShallowEq? Hello Ben, Tuesday, July 19, 2005, 11:01:32 AM, you wrote: BL I often find it useful to determine whether two objects are using the BL same constructor, without worrying about the constructors' arguments. BL There is way to hack together a partial implementation of the ShallowEq BL class within GHC, but it leaves much to be desired: BL instance Show a = ShallowEq a where BL([EMAIL PROTECTED]) a b BL= (head $ words $ show a) == (head $ words $ show b) reading GHC sources is always very interesting :) that is from GHC/Base.hs : %* %* * [EMAIL PROTECTED]@} %* * %* Returns the 'tag' of a constructor application; this function is used by the deriving code for Eq, Ord and Enum. The primitive dataToTag# requires an evaluated constructor application as its argument, so we provide getTag as a wrapper that performs the evaluation before calling dataToTag#. We could have dataToTag# evaluate its argument, but we prefer to do it this way because (a) dataToTag# can be an inline primop if it doesn't need to do any evaluation, and (b) we want to expose the evaluation to the simplifier, because it might be possible to eliminate the evaluation in the case when the argument is already known to be evaluated. \begin{code} {-# INLINE getTag #-} getTag :: a - Int# getTag x = x `seq` dataToTag# x \end{code} -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell] Dynamic binding
If we were on an OOP mailing list, I could ask for days how to simulate pattern matching and algebraic types---and get a nonsensical runaround involving the visitor pattern and huge swaths of unreadable code. In such a case, I would be happy if someone told me that there is work like this: http://www.cs.cornell.edu/Projects/jmatch/ People who wrote those papers clearly have thought harder of the problem than most subscribers to the preconceived OOP mailing list. Ralf, I think it's incumbent on you, having said several times that isn't solving the problem, to more clearly explain what problem you think exists and cannot be solved gracefully I am sure I said it. Also, Oleg and I should be fairly clear on all this in the OOHaskell paper. http://www.cwi.nl/~ralf/OOHaskell Major revision 13 June 2005 We will be grateful for additional comments and questions, and I am happy to summarize all feedback we get, if not on this mailing list, then in the paper's appendices, and elsewhere. Anyway, as it is incumbent on me to explain, I try to be as concise as I can get at 4.00am: [This should also cover Andreas' question.] 1. The original poster asked: What would be the normal way for a Haskell programmer to handle the typical shape example in beginner OO tutorials? 2. I take for granted that typical shape example is very well abstracted in this famous benchmark: http://onestepback.org/articles/poly/ http://www.angelfire.com/tx4/cus/shapes/ The essence of the typical shape example is the following: a there are different kinds of shapes (say rectangle, circle, whatever), b which are organized in a subtyping hierarchy, and c each kind of shape supports a subclass-specific draw method; d the interface of shapes allows for mutation/observation of state, e and eventually we want to process collections of shapes 3. Note that e) looks arbitrary at first sight, but it is crucial because shape apps will involve instances of the Composite pattern. Also note that the original poster indeed said: std::listshape * shapes; for(std::listshape *::iterator it = shapes.begin();it != shapes.end();++it) { (*it)-draw(...); } Also note that the body of the for loop happens to be a single statement that invokes draw, but obviously we must keep in mind what happens if the body is a compound statement. 4. Where did I say that isn't solving the problem? (( For the record, I did *not* say so when Lennart posted his proposal. I only mentioned that this proposal has the extensibility problem and that (minor issue) it needs extra effort to recover the same degree of type distinction as in the normal OO approach. )) Indeed, I did strongly disagree regarding the faithfulness of Bulat's attempts. He made two proposals. The first one basically suggested: - do not build a list of shapes, - do rather build a list of (lazy) applications of draw methods to shape construction arguments - then do not map over a list of shapes to perform functionality per element - do rather map over a list of expressions to sequence their effects. If you think of it, we can get rid of the generality of Haskell's map this way, which is something that others have thought of: http://lambda-the-ultimate.org/node/view/613 The second proposal by Bulat goes as follows: (again I save band with by not showing the actual code) - define a single *non-parameterized* datatype ShapeInterface - construct all sorts of shapes as terms over this monomorphic type - allow for state by IOref allocation before returning the shape terms - do *not* cover the problem of shapes with different interfaces - that is do really just pretend that all shapes have the same type - do therefore simplify away the issue of different types for different kinds of shapes - based on this simplification, build a homogeneous list of shapes - and do a reasonable loop with type-specific draw method invocations indeed. Again, if you think of it, we can adopt the same simplification strategy to Haskell. That is, in Haskell 20??, superclass constraints will not be allowed. We will recommend to define a single class in the recompilable Prelude to which we add methods as we encounter them. Ralf P.S.: I just realized that there is no OOCobol solution in the shapes repository. I sign for it. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding
I guess we just need to agree that we disagree. Of course, you are right that I am just a newbie when it comes to Haskell. How did you know that I am actually a Cobol programmer? Did you google? http://www.google.com/search?biw=1003hl=enq=Ralf+Cobol Seriously (?): 1. I never intended to impose any particular OO style on Haskeller's. Its more about the *intellectual* question whether we can take C++/C#/Java code and do a structure-preserving conversion to Haskell without starting to argue on paradigm conversion. Or as Alistair Bayley argues (Alistair, thanks for helping out!) http://www.haskell.org/tmrwiki/FpVsOo ... it might be that you need to interface with external OO code, or you are porting an existing program and need to remain faithful to the original design, if only because you don't understand it well enough to convert it to a functional design. ... Bulat, why not read all of this? Also see the end of that Wiki page, where a reference to a paper is given, which seems to solve all these problems, but my brain is to small to really be sure. ;-) 2. No matter how much you try, the code that you showed was not very close to a faithful Shapes implementation. If you dare to read the spec: http://onestepback.org/articles/poly/ http://www.angelfire.com/tx4/cus/shapes/ You made two proposals that don't solve the problem no matter of *style*: 1st proposal of Bulat: just create list of draw functions itself: [drawCircle (10,10) 5, drawSquare (20,20) 10] you are not expected that this problem can be solved with one line of code? :) My reply: you are not building a list of objects. You are not organizing a loop whose body iterates over a list and executes functionality. 2nd proposal of Bulat: for more complex tasks - declare interface as a structure: data ShapeInterface = Shape { draw :: IO (), moveTo :: Point - IO (), calcArea :: Float } and return this structures from constructor functions: circle x y r = Shape { draw = drawCircle center r, moveTo newCenter = , calcArea = pi*r*r } where center = Point x y square x y size = Shape { draw = , moveTo newCenter = , calcArea = size*szie } figures = [circle 1 2 3, square 4 5 6, circle 7 8 9] The tragedy here is that this stops to work once circles and squares do have different interfaces. You solution does not scale. Subtyping allows for interface extension, and the actual benchmark exploits this, but your code avoids it. Anyway the solution is trivial: ex. quantification, you didn't propose that. Cheers, Ralf (back to Cobol) -Original Message- From: Bulat Ziganshin [mailto:[EMAIL PROTECTED] Sent: Thursday, June 23, 2005 11:37 PM To: Ralf Lammel Cc: Pal-Kristian Engstad; haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding Hello Ralf, Thursday, June 23, 2005, 11:40:13 PM, you wrote: RL a) building (i) a list of data is fundamentally different RL from building (ii) a list of anticipated results of each datum. RL I would be surprised to hear that this counts as a valid technique. RL BTW, you can do the *same* in a lazy OO language. (No lazy OO language RL at hand -- well lazyness can be simulated.) sorry, valid technique is technique that work :) i use in my own program all the three ways i mentioned to solve problems of different complexity afair, you are relatively new to Haskell (relatively to my 1-year experience :) and, i think, you are not share FP thinking style. when programming in Haskell, i think in terms what thing i will need in this point of program?. if i need, for example, a possibility to check string against regular expression, then i will pass a function which does this check, not original RE. if i need a possibility to draw a shape, i will pass action which draws this shape. if i need several functions, i just combine them in a tuple there is one interesting example in my program. i have a list of wildcards and list of filenames and for each filename i need to know number of first wildcard to which this filename matched. in early stages of my program development i just passed list of wildcards to file-finding routine (as [Wildcard]). then, i changed list of wildcards to list of functions which check match against each wildcard ([Filename-Bool]). and after that, i changed this to one function which just finds first True answer (Filename-Int). it was also more effective to compute this function only one time (it was something compiled on moment of computing and worked as fast as hand-written analyzer for given set of wildcards) as you see, i slowly migrated from traditional way of solving this problem to perfectly functional way
RE: [Haskell-cafe] Re: [Haskell] Dynamic binding
Bulat wrote: if you require several operations, you can pack them in tuple or structure (really, tuple is a structure without field names) How are we going to anticipate all possible bodies of a for-loop? By comparison, when we build a normal Haskell list, does the construction precisely mirror what we are going to *do* with each element? Fold the map then!!! if you need fields/interfaces inheritance, then this method will not work. but in 90% of cases it's enough. What to do for the other 10%? in C++, creating classes is the most useful method of structuring program, so it is used for any problem - from very simple to most complex. when you translate such thing to Haskell, it's better to see which concrete problem are solved with help of classes, and not to emulate the classes itself (because in this case you will write many unneeded code) Yes, but we ought to solve the shapes problem. The shapes example is in Bulat's 10% region. only because it's C-like :) you just can't believe that Haskell program can be 3-10 times smaller while keeping the same functionality :))) But note that same functionality is one thing, having separate compilation and program extensibility too is another one. Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: [Haskell] Dynamic binding
But note that same functionality is one thing, having separate compilation and program extensibility too is another one. As I said, and as is well-known, extensibility is a red herring in this context - you merely trade one dimension of extensibility for another one. I am not going to fight for extensibility. It's just that I believe that there is a value in a direct correspondence as opposed to a transcription. I cite from the OOHaskell abstract: The [...] code [...] demonstrates that OO code translates into OOHaskell in an intuition-preserving way: essentially expression-by-expression, without requiring global transformations. I would like to add a peer-reviewed clear reference to the OOHaskell paper about the red herring that you mention. I don't have such a reference. May I kindly ask you to offer a few for selection? Thanks, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: [Haskell] Dynamic binding
Off-hand, I recall a paper by Martin Odersky and the Scala people discussing their approach to the Expression Problem, So ... http://icwww.epfl.ch/publications/documents/IC_TECH_REPORT_200433.pdf ... I guess The key innovative idea there is composition of mixins while replacing formal superclasses of mixins by the actual base class for mixin composition. I quote: In a mixin composition A with B with C, class A acts as actual superclass of mixins B and C, replacing the declared superclasses of B and C. To maintain type soundness, A must be a subclass of the declared superclasses of B and C. A super reference in either B or C will refer to a member of class A. As is the case for trait composition, Scala's mixin composition is commutative in the mixins - A with B with C is equivalent to A with C with B. In OOHaskell, you would parameterize in the superclass and that's it. DISCLAIMER: we haven't tried this. Thanks for the inspiration. and a related paper by Jacques Garrigue, where he proposes to solve it using OCaml's polymorphic variants. I am not sure. Is this referring to Objective Label? Which paper exactly? Hope this helps, It's interesting but I don't see how we make progress with the original (by now perhaps trivial) question regarding the transportation of an OO design into Haskell. The shapes problem doesn't call for Odersky's new contribution: I quote: We add to this list the following criterion: * Independent extensibility: It should be possible to combine independently developed extensions so that they can be used jointly [21]. The shapes problem rather calls for silly subtyping polymorphism. So we are beating a dead horse (or a red herring) by detouring to Scala unless I don't get you were hinting at. BTW, I just notice that Oderksy's list of partial solutions isn't complete: - Visitor combinators (Joost Visser) complementing Palsberg et al. - Many forms of generic functional programming (Hinze etc.) - Haskell type classes allow for extension in both type and processor extension. It's getting late here. Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: Re[2]: [Haskell] Dynamic binding
Bulat, Bulat wrote: just create list of draw functions itself: [drawCircle (10,10) 5, drawSquare (20,20) 10] No! the exercise is about lists of shapes not lists of results of drawing shapes. This is clearly a major difference. Bulat wrote: for more complex tasks - declare interface as a structure: data ShapeInterface = Shape { draw :: IO (), moveTo :: Point - IO (), calcArea :: Float } No! You miss the point that the different shapes differ regarding state types. You don't have a chance when you use one datatype. haskell-cafe? Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Bulat Ziganshin Sent: Thursday, June 23, 2005 12:18 AM To: Andrew Ward Cc: Pal-Kristian Engstad; haskell@haskell.org Subject: Re[2]: [Haskell] Dynamic binding Hello Andrew, Thursday, June 23, 2005, 5:38:03 AM, you wrote: AW To handle the problem of drawing all shapes, in c++, I would have a list AW of shape pointers: AW struct shape{ virtual void draw(...);}; AW struct circle : public shape {...}; AW struct square : public shape {...}; AW std::listshape * shapes; AW for(std::listshape *::iterator it = shapes.begin();it != AW shapes.end();++it) { (*it)-draw(...); } AW This general pattern of dynamic binding I use over and over again. Could AW you give me some example code of this type of thing handled in Haskell's AW way? Assuming that the number of classes deriving from shape might get AW quite large. just create list of draw functions itself: [drawCircle (10,10) 5, drawSquare (20,20) 10] you are not expected that this problem can be solved with one line of code? :) for more complex tasks - declare interface as a structure: data ShapeInterface = Shape { draw :: IO (), moveTo :: Point - IO (), calcArea :: Float } and return this structures from constructor functions: circle x y r = Shape { draw = drawCircle center r, moveTo newCenter = , calcArea = pi*r*r } where center = Point x y square x y size = Shape { draw = , moveTo newCenter = , calcArea = size*szie } figures = [circle 1 2 3, square 4 5 6, circle 7 8 9] of course, you cannot use inherited field names when using this technique :) -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: Re[2]: [Haskell] Dynamic binding
Andrew, you are circumventing the hard problem! (Even though I am sure you just forgot to mention it.) That is, the question is about drawing a *list* of shapes. As correctly observed by Rathman ages back, one naturally ends up with existential quantification when simulating dynamic binding. Ex. quantification is sufficiently scary for folks moving from C++ to Haskell. But fortunately it's not necessary ... see earlier plug ... Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of [EMAIL PROTECTED] Sent: Thursday, June 23, 2005 12:42 AM To: haskell@haskell.org Subject: Re: Re[2]: [Haskell] Dynamic binding G'day all. Thursday, June 23, 2005, 5:38:03 AM, you wrote: To handle the problem of drawing all shapes, in c++, I would have a list of shape pointers: struct shape{ virtual void draw(...);}; struct circle : public shape {...}; struct square : public shape {...}; std::listshape * shapes; for(std::listshape *::iterator it = shapes.begin();it != shapes.end();++it) { (*it)-draw(...); } This general pattern of dynamic binding I use over and over again. Could you give me some example code of this type of thing handled in Haskell's way? Assuming that the number of classes deriving from shape might get quite large. class Drawable s where draw :: s - IO () data Circle = Circle Point Radius instance Drawable Circle where draw (Circle centre radius) = ... If you only need interface inheritance, this should do. If you also need implementation inheritance, then you can model it with an upcast method: data Shape = Shape Stuff class Shape s where toShape :: s - Shape draw :: s - IO () instance Shape Shape where toShape s = s draw s = ... data Circle = Circle Shape Point Radius instance Shape Circle where toShape (Circle s _ _) = s draw (Circle _ centre radius) = ... In your original example, draw() wasn't abstract virtual, so I assume there's a reasonable default draw() method for your shape class. If there isn't, then it's probably better in Haskell to split the typeclass: class Shape s where toShape :: s - Shape class (Shape s) = DrawableShape s where draw :: s - IO () And only define DrawableShape on types where draw makes sense. Cheers, Andrew Bromage ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] Dynamic binding
Andreas Rossberg: Andreas R. wrote: dynamic binding is just the OOO way of saying calling a first-class function). Let me presume that dynamic binding was meant here in the sense of late binding, in the sense of subtyping polymorphism. At least, the given shapes example strongly suggested that. If so, I can't fully parse your reply in this context. Please elaborate. (First-class function seems to refer to currying or what?) (Did you miss a polymorphic before function? That would explain it. But then again, note, *first-class polymorphism* comes at the price of extra types just as the ugly ex. polymorphism trick. (This is of course just the same trick, indeed.) As we argue in Section 5.6 of the OOHaskell draft, current version, this does really not scale!) Andreas R. wrote: In typical functional programming style, you need the general thing only rarely. My impression is that the reason for not wanting (some do want however) true dynamic binding in Haskell relates more to the fact that we willingly make closed world assumptions about the cases to dispatch one. Where the C++ programmer defines classes, we are often just fine to define *one* datatype with n constructors (corresponding to n classes). In such a case, we have an easy time (except when we want case n+1 without recompilation). Using this idea, late binding degenerates to pattern matching, which is the value-level variation on VMT dispatch. (And for the rare cases, where we want to become polymorphic with an open world, we seem to be willing to sacrifice type inference and we engage into existential polymorphism / first-class polymorphism.) And then of course with normal Haskell type classes we can nicely simulate *interface* polymorphism (again modulo the lack of type inference for subtyping polymorphism). So pre-OOHaskell doesn't miss a lot ;-) Ralf ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell] Dynamic binding
Lennart, from a textbook perspective I agree that this solution should be mentioned to make it easy for non-Haskellers to get into the subject. However (as you of course know, but I just don't understand why you don't dare to mention the limitations a) and b) ...) a) Your constructor-based approach is not extensible. (Adding another form of shape requires touching existing code and recompilation.) I reckon that the (normal implied OO) point of the Shapes example, to a considerable extent, is also about the potential addition of new shapes. Saying we can take a snapshot of shape types and burn them into constructors of an algebraic type does not give me the impression of Haskell being ahead in type system and programming language arena. b) This burn subtypes into constructors leads me to a second weakness. By doing so, we have lost the precision of the original type dichotomy circle vs rectangle vs square since these guys are now all represented as terms of type. Of course, you might say that we could define dedicated types for circle, rectangle and square so that we would use the shape type merely as a *sum* type. (So constructors only serve for embedding.) This way we could at least recover the typing precision of OO. So I am willing to give in on b) but I maintain a) and I really miss extensible datatypes :-) Ralf (doing too much C# these days I guess) -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Lennart Augustsson Sent: Thursday, June 23, 2005 7:30 AM To: Andrew Ward Cc: haskell@haskell.org Subject: Re: [Haskell] Dynamic binding Andrew Ward wrote: Hi All, In Simon Thompson's The Craft of Functional Programming Second Edition, page 226, it is mentioned that Laufer (1996) describes a Haskell extension to allow dynamic binding. I was wondering if this has been implemented as an extension in any of the haskell compilers, or variants? I am a c++ programmer by trade, only dabbling in Haskell when I was at university, so it seems a disadvantage to me to not have dynamic binding in Haskell 98. What would be the normal way for a Haskell programmer to handle the typical shape example in beginner OO tutorials? Unlike previous posters that have shown various ways to simulate object oriented programming I'm going to try and answer the question. :) Here is what I would do: -- data Shape = Circle Point Radius | Square Point Size draw :: Shape - Pict draw (Circle p r) = drawCircle p r draw (Square p s) = drawRectangle p s s moveTo :: Shape - Point - Shape moveTo (Circle _ r) p = Circle p r moveTo (Square _ s) p = Square p s shapes :: [Shape] shapes = [Circle (0,0) 1, Square (1,1) 2] shapes' :: [Shape] shapes' = map (moveTo (2,2)) shapes -- This is in rather stark contrast to the object oriented way of doing the same things. For reference, here's how you could do it : -- class IsShape shape where draw :: shape - Pict moveTo :: Point - shape - shape data Shape = forall a . (IsShape a) = Shape a data Circle = Circle Point Radius instance IsShape Circle where draw (Circle p r) = drawCircle p r moveTo p (Circle _ r) = Circle p r data Square = Square Point Size instance IsShape Square where draw (Square p s) = drawRectangle p s s moveTo p (Square _ s) = Square p s shapes :: [Shape] shapes = [Shape (Circle (0,0) 10), Shape (Square (1,1) 2)] shapes' :: [Shape] shapes' = map (moveShapeTo (2,2)) shapes where moveShapeTo p (Shape s) = Shape (moveTo p s) -- Both ways of doing it contains the same information, it's just that it's organized in different ways. The functional way centers around the type Shape. You can find out all about what shapes exist by looking at the type definition. For each operation on shapes (draw moveTo) you describe what they do for the different shapes. The object oriented way centers more around the objects (surprise, surprise). For each kind of object you say that it's a shape and how the shape operations work. So, which is better? I don't think you can say one is better than the other. They have different strengths. With the object oriented way it is easy to answer questions like What is a Circle?, whereas with the functional way it is easy to answer How do you draw a Shape? Likewise, with the object oriented way it's easier to add a new kind of shape and with the functional way it's easier to add a new operation. To me it's a matter of taste. I like the functional taste; my brain has been warped over many years. -- Lennart ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org
RE: [Haskell-cafe] Re: Using type classes for polymorphism of dataconstructors
Thomas Sutton wrote: Main :t (Impl (Prop p) (Poss (Prop p)))-- p - p Impl (Prop p) (Poss (Prop p)) :: PC So the type says that this is a formula in the predicate calculus? (Even though you combine two formulae of modal logics.) Are you happy with that? Just wondering? Also, are you fine to take the conjunction of a PC and Modal formula, which is admitted by your types? (If not, you may want to use phantom types.) So it seems like the type doesn't carry a lot of information. Then we could also use different types. In particular, we could do without existentials. The types we get will (additionally) record the arity of the outermost constructor. (In your model, the type records the kind of logic of the outermost constructor.) class (Show f) = Formula f data PC0 = Prop String data Formula x = PC1 x = Neg x data (Formula x, Formula y) = PC2 x y = Conj x y | Disj x y | Impl x y instance Formula PC0 instance Formula x = Formula (PC1 x) instance (Formula x, Formula y) = Formula (PC2 x y) instance Show PC0 where show (Prop s) = s instance Formula x = Show (PC1 x) where show (Neg x) = ~ ++ show x instance (Formula x, Formula y) = Show (PC2 x y) where show (Conj a b) = (show a) ++ /\\ ++ (show b) show (Disj a b) = (show a) ++ \\/ ++ (show b) show (Impl a b) = (show a) ++ - ++ (show b) data Formula x = Modal1 x = Poss x | Necc x instance Formula x = Formula (Modal1 x) instance Formula x = Show (Modal1 x) where show (Poss a) = ++ (show a) show (Necc a) = [] ++ (show a) main = do print (Prop p) print (Poss (Prop p)) print (Impl (Prop p) (Poss (Prop p))) (Again, just wondering whether this might be an Ok solution.) Thomas Sutton wrote: In Java (C#, Python, etc) I'd do this ... Please post your Java code. I might want to add it to the OOHaskell demo suite. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Thomas Sutton Sent: Thursday, June 23, 2005 3:27 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Re: Using type classes for polymorphism of dataconstructors On 11/06/2005, at 11:18 PM, Thomas Sutton wrote: In Java (C#, Python, etc) I'd do this by writing an interface Formula and have a bunch of abstract classes (PropositionalFormula, ModalFormula, PredicateFormula, etc) implement this interface, then extend them into the connective classes Conjunction, Disjunction, etc. The constructors for these connective classes would take a number of Formula values (as appropriate for their arity). I've tried to implement this sort of polymorphism in Haskell using a type class, but I have not been able to get it to work and have begun to work on implementing this composition of logics in the DSL compiler, rather than the generated Haskell code. As solutions go, this is far from optimal. Can anyone set me on the right path to getting this type of polymorphism working in Haskell? Ought I be looking at dependant types? I've finally managed to find a way to get this to work using existentially quantified type variables and am posting it here for the benefit of the archives (and those novices like myself who will look to them in the future). My solution looks something like the following: A type class over which the constructors ought to be polymorphic: class (Show f) = Formula f where language :: f - String A type exhibiting such polymorphism: data PC = Prop String | forall a. (Formula a)= Neg a | forall a b. (Formula a, Formula b) = Conj a b | forall a b. (Formula a, Formula b) = Disj a b | forall a b. (Formula a, Formula b) = Impl a b instance Formula PC where language _ = Propositional Calculus instance Show PC where show (Prop s) = s show (Neg s)= ~ ++ (show s) show (Conj a b) = (show a) ++ /\\ ++ (show b) show (Disj a b) = (show a) ++ \\/ ++ (show b) show (Impl a b) = (show a) ++ - ++ (show b) Another such type: data Modal = forall a. (Formula a) = Poss a | forall b. (Formula b) = Necc b instance Formula Modal where language _ = Modal Logic instance Show Modal where show (Poss a) = ++ (show a) show (Necc a) = [] ++ (show a) Some example values of those types: Main :t (Prop p)-- p Prop p :: PC Main :t (Poss (Prop p))-- p Poss (Prop p) :: Modal Main :t (Impl (Prop p) (Poss (Prop p)))-- p - p Impl (Prop p) (Poss (Prop p)) :: PC I also have a sneaking suspicion I'd also be able to solve this problem using dependant types, but I have not investigated that approach. Cheers, Thomas Sutton ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org
[Haskell-cafe] RE: [Haskell] Dynamic binding
Andreas Rossberg said: [Followups to Haskell Cafe] as far as I read it, dynamic or late binding is orthogonal to subtyping, or typing in general. It is just that most typed OO languages lump these concepts together. Absolutely agreed. Often a simple first-class function, or a record thereof, is enough (in fact, dynamic binding is just the OOO way of saying calling a first-class function). In typical functional programming style, you need the general thing only rarely. Can you just tell how *you* would favor encoding the shapes example that was posed by poster? (It might just be that your code would be very close to Lennart's proposal?) Thanks, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding
Bulat, a) building (i) a list of data is fundamentally different from building (ii) a list of anticipated results of each datum. I would be surprised to hear that this counts as a valid technique. BTW, you can do the *same* in a lazy OO language. (No lazy OO language at hand -- well lazyness can be simulated.) Anyway, even if people end up coding as you propose, it won't work in general. Think of mutation methods that change the state but preserve the type. Then your list will still be heterogonous. NO? b) You wrote: this state is just don't need to appear in interface definition :) circle x y r You are not talking about state but constructor arguments. Please have a look here: http://www.angelfire.com/tx4/cus/shapes/cpp.html Circle Interface (Circle.h) class Circle: public Shape { public: Circle(int newx, int newy, int newradius); int getRadius(); void setRadius(int newradius); void draw(); private: int radius; }; [See getRadius and setRadius) In OO, mutable state tends to leak to the interface, perhaps not as public fields, perhaps not even as public proxy properties (but in the shapes example, it *does*), but then still as sublcass-specific interface member. Anyway, I am happy to add your and Lennart's proposals as appendices to the OOHaskell saga. And finally, Bulat, I agree with your point that original exercise was about OO way to solve some problem. i want to say that in Haskell it's better in most cases to use another, functional way Thanks, Ralf (returning to his VB problem) -Original Message- From: Bulat Ziganshin [mailto:[EMAIL PROTECTED] Sent: Thursday, June 23, 2005 4:55 AM To: Ralf Lammel Cc: Andrew Ward; Pal-Kristian Engstad; haskell-cafe@haskell.org Subject: Re[4]: [Haskell] Dynamic binding Hello Ralf, Thursday, June 23, 2005, 11:36:20 AM, you wrote: just create list of draw functions itself: [drawCircle (10,10) 5, drawSquare (20,20) 10] RL No! the exercise is about lists of shapes RL not lists of results of drawing shapes. RL This is clearly a major difference. in cases where you need to call only one function on created objects, you can just insert in list calls to this functions (not their results! i suppose that drawXXX functions has ... - IO () type) in cases where you need to call several functions for this object, you can insert in list tuple or structure for each object, as i do in next example. original exercise was about OO way to solve some problem. i want to say that in Haskell it's better in most cases to use another, functional way RL Bulat wrote: for more complex tasks - declare interface as a structure: data ShapeInterface = Shape { draw :: IO (), moveTo :: Point - IO (), calcArea :: Float } RL No! You miss the point that the different shapes RL differ regarding state types. RL You don't have a chance when you use one datatype. this state is just don't need to appear in interface definition :) see for example: data ShapeInterface = Shape { draw :: IO (), calcArea :: Float } circle x y r = Shape { draw = drawCircle x y r, calcArea = pi*r*r } square x y size = Shape { draw = drawSquare x y size, calcArea = size*szie } figures = [circle 1 2 3, square 4 5 6, circle 7 8 9] if you need to maintain mutable state, this is also not a problem: data ShapeInterface = Shape { draw :: IO (), moveTo :: (Int,Int) - IO (), calcArea :: Float } circle x y r = do center - ref (x,y) return Shape { draw = val center = drawCircle r , moveTo = (center=:) , calcArea = pi*r*r } main = do figures - sequence [circle 1 2 3, square 4 5 6, circle 7 8 9] mapM_ draw figures mapM_ (moveTo (0,0)) figures mapM_ draw figures ref=newIORef val=readIORef (=:)=writeIORef RL haskell-cafe? as you wish :) -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell] Dynamic binding
At the risk of being excluded from this list (because of an unmoral number of plugs about OOHaskell), here we go: http://homepages.cwi.nl/~ralf/OOHaskell/ You might start with the appendices of the paper and also read Section 2 which finally implements the Shapes example with ease. The C++ encoding is a bit verbose in so far that C++ doesn't quite have type inference, Haskell does and so OOHaskell does too :-) Apologies, Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Andrew Ward Sent: Wednesday, June 22, 2005 6:38 PM To: Pal-Kristian Engstad Cc: haskell@haskell.org Subject: Re: [Haskell] Dynamic binding Pal-Kristian Engstad wrote: On Wednesday 22 June 2005 05:38 pm, Andrew Ward wrote: What would be the normal way for a Haskell programmer to handle the typical shape example in beginner OO tutorials? By not doing OO. You have to ask yourself, what is the purpose and/or benefit of using OO? In C++, OO is _useful_ because you restrict the problems of mutable data (by enclosing it in C++ classes). ML type languages have other methods of doing things, and guess what, OO is not that needed for these languages. Sum-types, pattern-matching and data constructors make half of the need for OO go away. Higher order functions and make it even less needed. For the rest, there's always work-arounds. PKE. To handle the problem of drawing all shapes, in c++, I would have a list of shape pointers: struct shape{ virtual void draw(...);}; struct circle : public shape {...}; struct square : public shape {...}; std::listshape * shapes; for(std::listshape *::iterator it = shapes.begin();it != shapes.end();++it) { (*it)-draw(...); } This general pattern of dynamic binding I use over and over again. Could you give me some example code of this type of thing handled in Haskell's way? Assuming that the number of classes deriving from shape might get quite large. Andrew Ward. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
RE: [Haskell-cafe] [Newbie] Quest for inheritance
On 6/6/05, Gracjan Polak [EMAIL PROTECTED] wrote: 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. I heard about them indeed but barely found clear explanations of it. Any useful pointer you're aware of maybe ? Cédric Hi Cedric, See Section 7.3 of the latest revision of Haskell's overlooked object system. There are pointers and explanations. This discussion also clarifies that the phantom approach is tailored for foreign library and component import (but it can be generalized and has been indeed, by Burton in a paper from 1990). Regards, Ralf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] [Newbie] Quest for inheritance
There are tons of good research questions readily waiting. Such as: - What would we want to explore in OOish Haskell so that we, once more, can provide interesting input for mainstream language development? More specifically: what sorts of type inference would make a difference in Java 1.5+, C# 2.0+? - How would Haskell's type-class type system need to evolve in order to provide completely satisfying programmer experience for the uses of type classes in the various existing styles of OOish Haskell programmning? - We have Template Haskell but we are *still* rather lame when doing (OOish) language extensions. Macro systems with syntax extensions perhaps really open up a wormhole but nevertheless: *how* can we get a more experimental Haskell environment where language experiments make a good impression at the level of syntactic sugar, debugging, error messages, and all that? - How is it possible that Haskell lacks true extensible functions (modulo the kind of encoding I sent around earlier)? This is one of the big immediate benefits of OO mainstream programming. Seeing Haskell not providing them, makes me feel sad. It is also amazing that Haskell scores with complicated modes of extensibility (cf. monad transformers), but has no watertight answer when it comes to silly extensible datatypes (or classes) and functions (or methods) defined upon those. - ... Let's go to Sydney :-) (Or at the very least, let's meet at the Haskell Workshop!) Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Matthew Roberts Sent: Tuesday, June 07, 2005 12:15 AM To: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] [Newbie] Quest for inheritance I don't think this is publishable research, there is too much other stuff already out there. matt On 06/06/2005, at 5:58 PM, Gracjan Polak wrote: Matthew Roberts wrote: I have a project (for an early research student) waiting for an interested student to take on. It is called Programming patterns for OO-like programming in Haskell. The basic idea is to identify how to achieve OO-like organisation of your code in vanilla haskell. Hopefully the student can come to a deep understanding of OO and haskell programming in the process. ___ 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, http://homepages.cwi.nl/~ralf/OOHaskell/src/PoorMens2/ (again *not* using OOHaskell) From the quick skim of code: .?. -- apply function to upcast object .!. -- apply modification function to upcast object and substitute returned value (new object), basically update Absolutely. Is there any description avaliable what is PoorMens2 all about? Let me try. It's just a variation on Chris' encoding of the shape example, while trying to improve code reuse, while trying to highlight the commonalities in the data parts of the objects in the inheritance hierarchy. The approach ends up being similar to yours in so far that getters (and setters) can be made work for derived types once they are defined on the base type. I just notice that there is a short (because non-monadic) version: http://homepages.cwi.nl/~ralf/OOHaskell/src/PoorMens/ Ralf ___ 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, http://homepages.cwi.nl/~ralf/OOHaskell/src/PoorMens/ Good compromise between complexity, typing and usefulness. [unfortunately also limited, which is the reason that we came up with the monadic version: PoorMens2.] I noticed that both Rectangle and Circle need to redefine the operators because of the different names of their respective delegate to Shape, namely rectangle2shape and circle2shape. I we were to give these fields the same name ('parent', or 'super') in both Rectangle and Circle, could it be that we can avoid to redefine the operators by moving their definition upwards (and thus requiring only one definition for both classes) ? Won't work. ;-) Haskell standard records are not polymorphic like this. You can't write an operation that uses a record selector without committing to a specific record type. (With HList that underlies OOHaskell, of course, you can!!!) This is *precisely* the reason that: - Gracjan's code had a get_super. - my code has the generic .?. operator. We could try to give up on using normal records. That is, we could use a tuple convention where the first projection returns the data part of the base class, and the second projection returns the contribution of the derivation. However, this won't get us anywhere. We need the nominal types introduced by the new record types in order to represent the inheritance hierarchy in the type system (through the Inherits or Subtype classes). Would it then be a problem if we further subclass Rectangle in, say, two subclasses Square and NonSquareRectangle ? Would that still work or would there be a collision between the multiple 'parent' fields ? Due to the abovementioned reasons, any sort of parent fields will not interfere. Repeated inheritance simply leads to nested data composition; that's Ok. 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 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
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
RE: [Haskell-cafe] [Newbie] Quest for inheritance
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) 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 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? (( 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. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Cédric Paternotte Sent: Sunday, June 05, 2005 6:52 AM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] [Newbie] Quest for inheritance Hi. This is my first message here so Hello to everyone. I'm just starting to learn Haskell and I really think it's a cool language. Coming from an OO world, I've been looking for ways to achieve inheritance as you get it in Java and the likes. I know OO and inheritance is not really the point of Haskell and that other mechanisms are provided to somewhat achieve reuse. But it's a way of programming I've been so used to that I feel lost without it. You might think I'm heading in the wrong direction. My mistake I have to agree. Let's take it as a learning exercise then. So I've been searching the net for *easy* ways to get it and the least I can say is that I'm confused. It soon became apparent that, inheritance not being a core feature of the language, many people have been hacking Haskell to come up with similar effects (btw I never thought there could be so many ways to reach the same goal...Haskell programmers are clever bastards). Of the many implementations that I've found, few are really simple and most achieve it with various levels of success and/or dodgy syntax. Here are the various techniques I've come across so far : (I'm far from understanding them all) 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 ? 2. Through typeful heterogeneous collections This technique is described at http://homepages.cwi.nl/~ralf/OOHaskell/ and is able to bring most OO principles into Haskell. This seems to be a very good and thorough attempt. Unfortunately it looks more like a huge hack than a solution. The problem I have with it is the awkward syntax it requires, which to my newbie eyes doesn't look like Haskell anymore. 3. Through phantom types I couldn't find any idiot-proof documentation on this topic but this technique seems to be used to model inheritance. The few papers I've come across (http://research.microsoft.com/Users/simonpj/Papers/oo- haskell/overloading_conf.pdf , http://www.informatik.uni-bonn.de/~ralf/publications/Phantom.pdf ,http://www.informatik.uni-bonn.de/~ralf/publications/With.pdf ) seem very interesting but all go way over my head. 4. Through O'Haskell (http://www.cs.chalmers.se/~nordland/ohaskell/) Which is a non standard extension of Haskell that seems to be dead anyway. 5. With this : http://www.cs.utexas.edu/ftp/pub/techreports/tr01-60/tr01- 60.pdf This is a very interesting paper, at least for a newbie like me who's used to Java. The aim of this paper was to develop a same application in both Java and Haskell and to compare the resulting implementations afterwards. What interested me in this was
RE: GHC 6.4 release candidates available
I think this is an old bug, or at least I have seen it months back. The overlapping instances directive does not make it to the top-level. See attached sample with the offending session. Thanks for fixing. Ralf Test.hs Description: Test.hs ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
RE: GHC 6.4 release candidates available
It also worked in 6.2 Before that I don't remember. It is a very sensible thing to do simply because the mere ghci prompt suggests that we are in the scope of the top-level module. So one would really expect that ghci honors the directives of the top-level module. Ralf -Original Message- From: Keean Schupke [mailto:[EMAIL PROTECTED] Sent: Wednesday, March 02, 2005 9:20 AM To: Simon Peyton-Jones Cc: Ralf Lammel; glasgow-haskell-users@haskell.org Subject: Re: GHC 6.4 release candidates available In the past having: {-# OPTIONS -fallow-overlapping-instances #-} in a module was enough to get ghci to allow the overlaps. so we do: ghci Test.hs now it does not work (but it did in 6.3), but: ghci -fallow-overlapping-instances Test.hs does... Even it Test.hs is the top level module. Keean. Simon Peyton-Jones wrote: Ralf You have a pragma -fallow-overlapping-instances in Test.hs, and indeed it is honoured when compiling Test.hs. But it's not taken into account when compiling top-level expressions, or, indeed, if you were to import Test into another module. If you say :set -falllow-overlapping-instances it'll work fine. Now, maybe you'd like the flag to attach permanently to the *instance*, so that if an instance decl is compiled with -fallow-overlapping-instances, then no complaint will ever be issued for its overlaps, even if it is imported into a module that doesn't have -fallow-overlapping-instances. That would make sense, I think, but it's not implemented and never has been. Simon | -Original Message- | From: [EMAIL PROTECTED] [mailto:glasgow-haskell-users- | [EMAIL PROTECTED] On Behalf Of Ralf Lammel | Sent: 02 March 2005 08:45 | To: glasgow-haskell-users@haskell.org | Subject: RE: GHC 6.4 release candidates available | | I think this is an old bug, | or at least I have seen it months back. | | The overlapping instances directive does not make it to the top-level. | See attached sample with the offending session. | | Thanks for fixing. | Ralf ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
RE: Scrap your boilerplate (but don't scrap them precious comments)
That's a very good point. Me too, I would often wish to see some principled code details when entering documentation. For instance what is the point of _explaining_ that inc aliases add 1, why not just show that equation! I agree that gmap?? are a bit of this kind. It is so much easier to explain them, while showing code. It is so much of a hassle to explain them while not showing code. The implementations of gmap?? are almost like algebraic properties ... I mean these are rather principled implementations. A documentation tool should support algebraic laws _and_ such principled implementations. It would really help to link the function signatures with the function definitions in the sense of a limited code browsing functionality. I am sure this is not a new discussion topic, but we really need this IMHO. Ralf -Original Message- From: [EMAIL PROTECTED] [mailto:glasgow-haskell- [EMAIL PROTECTED] On Behalf Of Benjamin Franksen Sent: Monday, February 28, 2005 4:11 PM To: glasgow-haskell-users@haskell.org Subject: Scrap your boilerplate (but don't scrap them precious comments) Hi, I have been racking my brain over the infamous 'gfoldl' and 'gunfold' combinators. (Yes, I have read the papers). What finally made me understand how they worked was reading the code: first the implementation of the gmap functions (Data/Generics/Basics.hs), then the long and detailed comments in the same file, and finally the instance definitions for the built-in types (in Data/Generics/Instances.hs). IMHO, a lot of this could and should be part of the (haddock-generated) documentation. It is such a waste: all these wonderful comments in the source file, that could be added to the docs with a keystroke! Instead, they simply say Left-associative fold operation for constructor applications which is really a bit terse for gfoldl, of which the source file comment (rightly) states that its type is a headache. Furthermore, (example) implementations can sometimes be extremely helpful to understand things; this is especially true for a language like Haskell, in which the implementation is often already the shortest (or at least a very short) and most precise way to specify a functions semantics. In this case, the implementations of gfoldl helped me to understand what the function itself does. However, how and why these extremely abstract combinators can serve as the basic building blocks of all the more concrete and better understandable variants is best documented by the implementation of just these variants gmapXX and friends. (Maybe one or two examples implementations would suffice). At least, it should be stated in the docs what the type constructor ('c') is in each case. I don't know if haddock can add the implementation of a function to the documentation. If not, such a feature should be considered. SYB is a wonderful piece of work and deserves to be documented as well as it is programmed. Ben ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
[Haskell] Call for participation: Summerschool on Gen. and Transf. Techn. in SE, 4-8 July 2005, Braga
Please find attached the call for participation for the Summer School on Generative and Transformational Techniques in Software Engineering 4 - 8 July, 2005, Braga, Portugal http://www.di.uminho.pt/GTTSE2005 Registration is open. There are 17 confirmed tutorials and other presentations. -- Ralf Lammel http://homepages.cwi.nl/~ralf/ Summer School on Generative and Transformational Techniques in Software Engineering 4 - 8 July, 2005, Braga, Portugal http://www.di.uminho.pt/GTTSE2005 SCOPE AND FORMAT The summer school brings together PhD students, lecturers, technology presenters, as well as other researchers and practitioners who are interested in the generation and the transformation of programs, data, models, meta-models, and documentation. This concerns many areas of software engineering: software reverse and re-engineering, model-driven approaches, automated software engineering, generic language technology, to name a few. These areas differ with regard to the specific sorts of meta-models (or grammars, schemas, formats etc.) that underly the involved artifacts, and with regard to the specific techniques that are employed for the generation and the transformation of the artifacts. The tutorials are given by renowned representatives of complementary approaches and problem domains. Each tutorial combines foundations, methods, examples, and tool support. The program of the summer school also features invited technology presentations, which present setups for generative and transformational techniques. These presentations complement each other in terms of the chosen application domains, case studies, and the underlying concepts. Furthermore, the program of the school also features a participants workshop. All students of the summer school will be invited to give a presentation about their ongoing work. They will be asked to submit a title and an abstract beforehand. The senior researchers present at the summer school will provide the students with feedback on their presentations. All summer school material will be collected in proceedings that are handed out to the participants. Formal proceedings will be compiled after the summer school, where all contributions are subjected to additional reviewing. The formal proceedings will be published in the Lecture Notes in Computer Science series of Springer. TUTORIALS * Don Batory (The University of Texas at Austin): Feature Oriented Programming * Ira Baxter (Semantic Designs Inc.): Compiling Fast XML reader/writers from DTDs using Program Transformations * Jean Bezivin (INRIA, LINA, University of Nantes): Metamodelling and Model Driven Software Development * Shigeru Chiba (Tokyo Institute of Technology): Program Transformation With Reflective and Aspect-Oriented Programming * Jean-Luc Hainaut (University of Namur): The Transformational Approach to Database Engineering * Zhenjiang Hu (University of Tokyo): Program Optimization and Transformation in Calculational Forms * Erik Meijer (Microsoft, Redmond): Object, relational, and XML mapping * Tom Mens (University of Mons-Hainaut): On the Use of Graph Transformations for Model Refactoring TECHNOLOGY PRESENTATIONS The purpose of the technology presentations is to supplement the theoretical knowledge acquired in the tutorials with practical knowledge of how generative and transformational tool support can be instrumental in solving software engineering problems. Technology presentations can include, but are not limited to demonstration of the features of a single tool. Rather, they include: * Reference to the concepts behind the technology * Application of the technology to a case study of non-trivial scale * Clear statement of benefits and limitations of the technology The participants will have ample opportunity to interact in informal manner with the technology presenters. Confirmed technology presentations: (Note: titles and authors abbreviated) * Mark van den Brand (CWI HvA, The Netherlands) et al.: Applications of the ASF+SDF Meta-Environment * Martin Bravenboer (Utrecht University, The Netherlands) et al.: Domain-specific Language Embedding using Stratego/XT and MetaBorg * Thomas R. Dean (Queen's University, Canada): Applications of Agile Parsing To Web Services * Helena Galhardas (IST Tagus Park, Portugal): Data cleaning and transformation using te AJAX framework * Dirk Heuzeroth (sdm AG, Germany) et al.: A Tool Suite for Invasive Software Composition * Frederic Jouault (Université de Nantes, France): Model Transformation and Weaving Tools in the AMMA Platform * Günter Kniesel (University of Bonn): Refactoring based on Composable Conditional Program Transformations * Victor Winter (University of Nebraska at Omaha, USA): Software transformation with HATS' Higher-Order Transformation * Albert Zündorf (University of Kassel, Germany): Model Driven Software Development with Fujaba VENUE The summer school will be held in the northern region