Re: [Haskell-cafe] [RFC] benchmarks of bytestrings, teaser
On Sun, 2007-12-16 at 15:21 -0800, Don Stewart wrote: An updated bytestring library is at : http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bytestring-0.9.0.2 Enjoy! :) Thanks! -Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Monads that are Comonads and the role of Adjunction
Derek Elkins wrote: There is another very closely related adjunction that is less often mentioned. ((-)-C)^op -| (-)-C or a - b - C ~ b - a - C This gives rise to the monad, M a = (a - C) - C this is also exactly the comonad it gives rise to (in the op category which ends up being the above monad in the normal category). That looks very like the type of mfix. Is this related to MonadFix? Thanks, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] OOP'er with (hopefully) trivial questions.....
I'm trying to teach myself HaskellI've spent a few hours going through a few tutorialsand I sort of get the basics... My interest in Haskell is specifically around the strength of the type system. After many years of OOP though my brain is wired up to construct software in that 'pattern'a problem for me at the moment is I cannot see how to construct programs in an OO style in HaskellI know this is probably not the way to approach it...but I feel I need to master the syntax before the paradigm. I'm not fussed about mutability, and I'm not fussed about implementation inheritance (as apposed to subtyping) my concerns are encapsulation of 'state' and abstraction, and extension/expansiona simple example would be. interface IShape { Int GetArea(); } class Square : IShape { Readonly int length; Public Square(int length) { this.length = length; } Int GetArea() { return length * length;} } Class Rectangle : IShape { Readonly int lengthA; Readonly int lengthB; Public Rectangle (int lengthA,int lengthB) { this.lengthA = lengthA; this.lengthB = lengthB; } Int GetArea() { return lengthA * lengthB;} } Class Circle : IShape { Readonly int radius; Public Circle(int radius) { this.radius = radius; } Int GetArea() { return pi * radius * radius;} } Client code. Void Foo(IShape shape) { // look!I know nothing except its of type IShape. Int area = shape.GetArea(); } I can obviously at a later date add a new class Triangle, and not have to touch any of the above code ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 17 Dec 2007, at 10:46, Nicholls, Mark wrote: I can obviously at a later date add a new class Triangle, and not have to touch any of the above code…. Yes, and you can indeed do a similar thing in Haskell. The natural thing to do here would be to define a type Shape... data Shape = Circle Int | Rectangle Int Int | Square Int area :: Shape - Int -- Note, this is an interesting type if you want the area of circles area (Circle r) = pi * r^2 area (Rectangle h w) = h * w area (Square l) = area (Rectangle l l) If however, you *really* want to keep your shapes as being seperate types, then you'll want to invoke the class system (note, not the same as OO classes). class Shape a where area :: a - Int newtype Circle = C Int instance Shape Circle where area (C r) = pi * r^2 newtype Rectangle = R Int Int instance Shape Rectangle where area (R h w) = h * w newtype Square = Sq Int instance Shape Square where area (Sq l) = l * l -- Now we can do something with our shapes doubleArea :: Shape a = a - Int doubleArea s = (area s) * 2 Hope that helps Bob___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Nicholls, Mark [EMAIL PROTECTED] writes: After many years of OOP though my brain is wired up to construct software in that ?pattern??.a problem for me at the moment is I cannot see how to construct programs in an OO style in Haskell?.I know this is probably not the way to approach it?but I feel I need to master the syntax before the paradigm. Mostly, you'd use an algebraic data type. I.e. data Shape = Square Int | Rectangle Int Int | Circle Int area :: Shape - Int area (Square x) = x^2 area (Rectangle x y) = x * y area (Circle r) = pi*r^2 -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
OK I'll have to digest this and mess about a bitbut can I make an observation at this point If I define Shape like data Shape = Circle Int | Rectangle Int Int | Square Int Isn't this now closed...i.e. the statement is effectively defining that shape is this and only ever thisi.e. can I in another module add new types of Shape? (sorry about all the quotation marks, but it's a minefield of potential confusions over types, classes etc). My other observation is...are the things on the right hand side of the the ='s sign not types? The lower version makes more sense to me...I'll have to give it a go A P.S. would be...I tend to write code rather than mess about in the GHCi shell.is there a way in code to output the type of a value..i.e. the :t operation? -Original Message- From: Thomas Davie [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 11:04 To: Nicholls, Mark Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On 17 Dec 2007, at 10:46, Nicholls, Mark wrote: I can obviously at a later date add a new class Triangle, and not have to touch any of the above code Yes, and you can indeed do a similar thing in Haskell. The natural thing to do here would be to define a type Shape... data Shape = Circle Int | Rectangle Int Int | Square Int area :: Shape - Int -- Note, this is an interesting type if you want the area of circles area (Circle r) = pi * r^2 area (Rectangle h w) = h * w area (Square l) = area (Rectangle l l) If however, you *really* want to keep your shapes as being seperate types, then you'll want to invoke the class system (note, not the same as OO classes). class Shape a where area :: a - Int newtype Circle = C Int instance Shape Circle where area (C r) = pi * r^2 newtype Rectangle = R Int Int instance Shape Rectangle where area (R h w) = h * w newtype Square = Sq Int instance Shape Square where area (Sq l) = l * l -- Now we can do something with our shapes doubleArea :: Shape a = a - Int doubleArea s = (area s) * 2 Hope that helps Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 17 Dec 2007, at 11:14, Nicholls, Mark wrote: OK I'll have to digest this and mess about a bitbut can I make an observation at this point If I define Shape like data Shape = Circle Int | Rectangle Int Int | Square Int Isn't this now closed...i.e. the statement is effectively defining that shape is this and only ever thisi.e. can I in another module add new types of Shape? (sorry about all the quotation marks, but it's a minefield of potential confusions over types, classes etc). That's correct, another module could not add constructors to this type. The idea here is that you tell it all of the possible ways to construct Shape, and can then write functions to deal with it elsewhere. My other observation is...are the things on the right hand side of the the ='s sign not types? Correct, they're constructors. So you could never for example write a function that accepts only Rectangles (unless you start getting into odd type extensions) The lower version makes more sense to me...I'll have to give it a go Both versions make sense. They differ only in how heavy weight they are. Defining a type allows you to do pattern matching on the constructors, and is a much better way of defining anything you know the structure of in the first place. Using the class system on the other hand, gives you more flexibility, but at the cost of a lot of readability. The class system is designed to be able to describe things that aren't explicitly the same type, but exhibit similar properties. For example the Eq class describes all things that are equatable, it defines the (==) and (/=) operators. Your Shape class describes all types in which it's sane to compute an area. A P.S. would be...I tend to write code rather than mess about in the GHCi shell.is there a way in code to output the type of a value..i.e. the :t operation? Take a look at the Typable class. Although, pretty much any code that you can compile can be loaded into ghci without modification, and that's by far the easier way of finding the types of things. Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: array documentation is missing
I have received patches which will help Cabal make ghc-6.6 and gc-6.8 friendly regex-tdfa. The problem below is from a change in STUArray from 3 to 4 parameters going from 6.6 to 6.8. I think adding another '_' to each pattern match makes it work for 6.8. Once I get these patches working locally I will push out new versions of regex-* packages. Though I cannot test 6.8.x until it starts working on powerpc OS X 10.5. Thomas Hartman wrote: While trying to make Regex.TDFA 0.91 install on 6.8.2 I got [10 of 21] Compiling Text.Regex.TDFA.RunMutState ( Text/Regex/TDFA/RunMutState.\ hs, dist\build/Text/Regex/TDFA/RunMutState.o ) Text/Regex/TDFA/RunMutState.hs:601:9: Constructor `STUArray' should have 4 arguments, but has been given 3 In the pattern: STUArray _ _ msource In the definition of `copySTU': copySTU (STUArray _ _ msource) (STUArray _ _ mdest) = ST $ \ s1# - case sizeofMutableByteArray# msource of n# -\ ... ^[]0;~/hackageTarGzs/regexstuff/regex-tdfa-0.92^G [EMAIL PROTECTED] ^[[33m~/hackageTarGzs/regexstuff/regex-tdfa-0.92^[\ [0m but I got stuck fixing it because the array documentation isn't there http://www.haskell.org/ghc/docs/latest/html/libraries/haskell98/Array.html assume I'm getting the above error because the array interface has changed thomas. --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. ___ 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] OOP'er with (hopefully) trivial questions.....
Ooo The constructor of a newtype must have exactly one field but `R' has two In the newtype declaration for `Rectangle' It doesn't like newtype Rectangle = R Int Int -Original Message- From: Thomas Davie [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 11:04 To: Nicholls, Mark Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On 17 Dec 2007, at 10:46, Nicholls, Mark wrote: I can obviously at a later date add a new class Triangle, and not have to touch any of the above code Yes, and you can indeed do a similar thing in Haskell. The natural thing to do here would be to define a type Shape... data Shape = Circle Int | Rectangle Int Int | Square Int area :: Shape - Int -- Note, this is an interesting type if you want the area of circles area (Circle r) = pi * r^2 area (Rectangle h w) = h * w area (Square l) = area (Rectangle l l) If however, you *really* want to keep your shapes as being seperate types, then you'll want to invoke the class system (note, not the same as OO classes). class Shape a where area :: a - Int newtype Circle = C Int instance Shape Circle where area (C r) = pi * r^2 newtype Rectangle = R Int Int instance Shape Rectangle where area (R h w) = h * w newtype Square = Sq Int instance Shape Square where area (Sq l) = l * l -- Now we can do something with our shapes doubleArea :: Shape a = a - Int doubleArea s = (area s) * 2 Hope that helps Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On Dec 17, 2007 10:47 PM, Nicholls, Mark [EMAIL PROTECTED] wrote: The constructor of a newtype must have exactly one field but `R' has two In the newtype declaration for `Rectangle' It doesn't like newtype Rectangle = R Int Int A newtype can only have one constructor, with one argument, and is essentially a wrapper for that argument type. In the general case, you want to use data instead of newtype: data Rectangle = R Int Int Stuart ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 17 Dec 2007, [EMAIL PROTECTED] wrote: Ooo The constructor of a newtype must have exactly one field but `R' has two In the newtype declaration for `Rectangle' It doesn't like newtype Rectangle = R Int Int You want data Rectangle = R Int Int A newtype declaration will be completely erased at compile time. That is, when you have a declaration like newtype Circle = C Int the compiled code will not be able to distinguish between a Circle and an Int. You do, however, get all the benefits of a separate entity in the type system. When your type only has one constructor, newtype is preferred over data, but they are semantically equivalent. There are extensions which provide impressive newtype-deriving-foo (getting the compiler to write fairly non-trivial instance declarations for you). Jed pgp595ILQHSg7.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Questions about the Functor class and it's use in Data types à la carte
Dominic Steinitz wrote: Roberto Zunino wrote: This is the point: eta does not hold if seq exists. undefined `seq` 1 == undefined (\x - undefined x) `seq` 1 == 1 Ok I've never used seq and I've never used unsavePerformIO. Provided my program doesn't contain these then can I assume that eta reduction holds and that (.) is categorical composition? Yes, provided that you do not use seq and all its related stuff, e.g. ($!), foldl', bang patterns, data Foo a = Foo !a, ... Also, note that you still can define and use seq restricted to many useful types: seqInt :: Int - a - a seqInt 0 x = x seqInt _ x = x IIRC, you can also have a quite general seqData :: Data a = a - b - b The (.) does not form a category argument should be something like: id . undefined == (\x - id (undefined x)) /= undefined where the last inequation is due to the presence of seq. That is, without seq, there is no way to distinguish between undefined and (const undefined), so you could use a semantic domain where they coincide. In that case, eta does hold. It would be a pretty odd semantic domain where 1 == undefined. Or perhaps, I should say not a very useful one. in the new domain, you do not have 1 == undefined (which are still different) but merely undefined == (\x - undefined) Regards, Zun. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Ok... Thanks I need to revisit data and newtype to work out what the difference is I think. -Original Message- From: Jed Brown [mailto:[EMAIL PROTECTED] On Behalf Of Jed Brown Sent: 17 December 2007 12:04 To: Nicholls, Mark Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On 17 Dec 2007, [EMAIL PROTECTED] wrote: Ooo The constructor of a newtype must have exactly one field but `R' has two In the newtype declaration for `Rectangle' It doesn't like newtype Rectangle = R Int Int You want data Rectangle = R Int Int A newtype declaration will be completely erased at compile time. That is, when you have a declaration like newtype Circle = C Int the compiled code will not be able to distinguish between a Circle and an Int. You do, however, get all the benefits of a separate entity in the type system. When your type only has one constructor, newtype is preferred over data, but they are semantically equivalent. There are extensions which provide impressive newtype-deriving-foo (getting the compiler to write fairly non-trivial instance declarations for you). Jed ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: announcing darcs 2.0.0pre2
David Roundy wrote: I am pleased to announce the availability of the second prerelease of darcs two, darcs 2.0.0pre2. Thanks! Continuing my performance tests, I tried unpulling and re-pulling a bunch of patches in a GHC tree. I'm unpulling about 400 patches using --from-tag, and then pulling them again from a local repo. Summary: darcs2 is about 10x slower than darcs1 on unpull, and on pull it is 100x slower in user time but only 20x slower in elapsed time. In both cases, the repository was on an NFS filesystem. In the darcs2 case, the repository I was pulling from was on the local disk, and I'm also using a cache (NFS-mounted). The darcs2 repository has been optimized, but the darcs1 repository has not (at lesat, not recently). I did all of these a couple of times to eliminate the effects of cache preloading etc., the times reported are from the second run. --- darcs 1: $ time darcs unpull --from-tag 2007-09-25 -a Finished unpulling. 35.17s real 5.77s user 1.00s system 19% darcs unpull --from-tag 2007-09-25 -a $ time darcs pull ~/ghc-HEAD -a Pulling from /home/simonmar/ghc-HEAD... 33.51s real 3.62s user 1.05s system 13% darcs pull ~/ghc-HEAD -a --- darcs 2: $ time darcs2 unpull --from-tag 2007-09-25 -a Finished unpulling. 385.22s real 52.18s user 12.62s system 16% darcs2 unpull --from-tag 2007-09-25 -a $ time darcs2 pull /64playpen/simonmar/ghc-darcs2 -a Finished pulling and applying. 668.75s real 290.74s user 15.03s system 45% darcs2 pull /64playpen/simonmar/ghc-darcs2 -a Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 17 Dec 2007, at 12:22, Nicholls, Mark wrote: Ok... Thanks I need to revisit data and newtype to work out what the difference is I think. Beware in doing so -- type, and newtype are not the same either. type creates a type synonim. That is, if I were to declare type Jam = Int then Jam and Int from that point on become completely interchangable, the only thing this does is make things readable. For example, a parser might be described as a function that takes a list of tokens, and outputs a parse tree, and a list of unparsed tokens: type Parser = [Token] - (ParseTree, [Token]) if I write some parser combinators, I can now give them clear types like | :: Parser - Parser - Parser I could however still write this, and it would have *exactly* the same meaning. | :: ([Token] - (ParseTree, [Token])) - ([Token] - (ParseTree, [Token])) - [Token] - (ParseTree, [Token]) newtype on the other hand introduces a new type to the type system. Because of this, the type system has to be able to tell when you're using your new type, so a tag gets attached. newtype Ham = Ham Int This creates a type that contains only an integer, but is different from Int (and Jam) in the type system's eyes. Thus, I cannot for example write (Ham 5) + (Ham 6) Because Ham is not Int and thus (+) does not work (or actually, more specifically, Ham is not a member of the class Num, the numeric types, and therefore (+) doesn't work). This can of course be fixed thus: newtype Ham = Ham Int deriving Num Hope that helps Tom Davie p.s. Sorry for the slip with the newtype Rectangle. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
Nicholls, Mark wrote: data Shape = Circle Int | Rectangle Int Int | Square Int Isn't this now closed...i.e. the statement is effectively defining that shape is this and only ever thisi.e. can I in another module add new types of Shape? Yes, but in most cases, this is actually a good thing. For instance, you can now define equality of two shapes: equal :: Shape - Shape - Bool equal (Circle x)(Circle y)= x == y equal (Rectangle x1 x2) (Rectangle y1 y2) = x1 == x2 y1 == y2 equal (Square x)(Square y)= x == y In general, the open approach is limited to functions of the form Shape - ... - Shape / Int / something else with no Shape occurring in the other ... arguments. I'm trying to teach myself HaskellI've spent a few hours going through a few tutorialsand I sort of get the basics... [...] After many years of OOP though my brain is wired up to construct software in that 'pattern'a problem for me at the moment is I cannot see how to construct programs in an OO style in HaskellI know this is probably not the way to approach it...but I feel I need to master the syntax before the paradigm. This approach is probably harder than it could be, you'll have a much easier time learning it from a paper-textbook like http://www.cs.nott.ac.uk/~gmh/book.html http://web.comlab.ox.ac.uk/oucl/publications/books/functional/ http://haskell.org/soe/ After all, it's like learning programming anew. Regards, apfelmus ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
No that's fineits all as clear as mud!..but that's not your fault. To recap... type introduces a synonym for another type, no new type is createdit's for readabilities sake. Newtype introduces an isomorphic copy of an existing type...but doesn't copy it's type class membership...the types are disjoint/distinct but isomorphic (thus only 1 constructor param). data introduces a new type, and defines a composition of existing types to create a new one based on - and (. class introduces a constraint that any types declaring themselves to be a member of this class...that functions must exist to satisfy the constraint. I'm sure that's wrong, but it's a good as I've got at the moment. And to a degree it's all upside downwhat Haskell thinks are types...I think are singnatures and what Haskell thinks is a type class I think of as a type.it's not going to be easy. -Original Message- From: Thomas Davie [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 12:35 To: Nicholls, Mark Cc: Haskell Cafe Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On 17 Dec 2007, at 12:22, Nicholls, Mark wrote: Ok... Thanks I need to revisit data and newtype to work out what the difference is I think. Beware in doing so -- type, and newtype are not the same either. type creates a type synonim. That is, if I were to declare type Jam = Int then Jam and Int from that point on become completely interchangable, the only thing this does is make things readable. For example, a parser might be described as a function that takes a list of tokens, and outputs a parse tree, and a list of unparsed tokens: type Parser = [Token] - (ParseTree, [Token]) if I write some parser combinators, I can now give them clear types like | :: Parser - Parser - Parser I could however still write this, and it would have *exactly* the same meaning. | :: ([Token] - (ParseTree, [Token])) - ([Token] - (ParseTree, [Token])) - [Token] - (ParseTree, [Token]) newtype on the other hand introduces a new type to the type system. Because of this, the type system has to be able to tell when you're using your new type, so a tag gets attached. newtype Ham = Ham Int This creates a type that contains only an integer, but is different from Int (and Jam) in the type system's eyes. Thus, I cannot for example write (Ham 5) + (Ham 6) Because Ham is not Int and thus (+) does not work (or actually, more specifically, Ham is not a member of the class Num, the numeric types, and therefore (+) doesn't work). This can of course be fixed thus: newtype Ham = Ham Int deriving Num Hope that helps Tom Davie p.s. Sorry for the slip with the newtype Rectangle. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On Mon, 17 Dec 2007, Nicholls, Mark wrote: After many years of OOP though my brain is wired up to construct software in that 'pattern'a problem for me at the moment is I cannot see how to construct programs in an OO style in HaskellI know this is probably not the way to approach it...but I feel I need to master the syntax before the paradigm. This issue is rather a FAQ. Let's look what our Wiki provides: http://www.haskell.org/haskellwiki/OOP_vs_type_classes ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
Not really with this... The open case (as in OO) seems to be more like the Haskell class construct, i.e. if new types declare themselves to be members of a class then they must satisfy certain constaintsI can then specify equals with the class and leave the onus on the implementor to implement itthe data construct seems more analogous to a OO class definition...which is closed in the same way. The approach is deliberate...but I accept may be harder than it needs to be...I'm interested in Haskell because of the alleged power/formality of it's type system against the relatively weakness of OO ones...the irony at the moment is that they do not really seem to correspond directlyand OO type system seems to (loosely) correlate to Haskell type class system, and an OO class system (loosely) to Haskels type system, though in OOP's they are unpleasantly tangled. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of apfelmus Sent: 17 December 2007 12:34 To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Re: OOP'er with (hopefully) trivial questions. Nicholls, Mark wrote: data Shape = Circle Int | Rectangle Int Int | Square Int Isn't this now closed...i.e. the statement is effectively defining that shape is this and only ever thisi.e. can I in another module add new types of Shape? Yes, but in most cases, this is actually a good thing. For instance, you can now define equality of two shapes: equal :: Shape - Shape - Bool equal (Circle x)(Circle y)= x == y equal (Rectangle x1 x2) (Rectangle y1 y2) = x1 == x2 y1 == y2 equal (Square x)(Square y)= x == y In general, the open approach is limited to functions of the form Shape - ... - Shape / Int / something else with no Shape occurring in the other ... arguments. I'm trying to teach myself HaskellI've spent a few hours going through a few tutorialsand I sort of get the basics... [...] After many years of OOP though my brain is wired up to construct software in that 'pattern'a problem for me at the moment is I cannot see how to construct programs in an OO style in HaskellI know this is probably not the way to approach it...but I feel I need to master the syntax before the paradigm. This approach is probably harder than it could be, you'll have a much easier time learning it from a paper-textbook like http://www.cs.nott.ac.uk/~gmh/book.html http://web.comlab.ox.ac.uk/oucl/publications/books/functional/ http://haskell.org/soe/ After all, it's like learning programming anew. Regards, apfelmus ___ 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] Re: OOP'er with (hopefully) trivial questions.....
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Nicholls, Mark The open case (as in OO) seems to be more like the Haskell class construct, i.e. if new types declare themselves to be members of a class then they must satisfy certain constaintsI can then specify equals with the class and leave the onus on the implementor to implement itthe data construct seems more analogous to a OO class definition...which is closed in the same way. This may or may not help, but anyway... As Henning has pointed out, this is a FAQ. However, his recommended page (OOP_vs_type_classes) is quite involved. As a counterpoint, I really liked Lennart's example and summary from a couple of years ago: http://www.haskell.org/pipermail/haskell/2005-June/016058.html (I've added it to section 5 of this page: http://www.haskell.org/haskellwiki/Existential_type) The key point (IMO): 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. Alistair * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
On Dec 17, 2007 1:18 PM, Nicholls, Mark [EMAIL PROTECTED] wrote: Not really with this... The open case (as in OO) seems to be more like the Haskell class construct, i.e. if new types declare themselves to be members of a class then they must satisfy certain constaintsI can then specify equals with the class and leave the onus on the implementor to implement itthe data construct seems more analogous to a OO class definition...which is closed in the same way. Yes that's pretty much true. In lots of cases you do have tons of different representations of a specific type that is known at to be closed. E.g. singly linked list has two cases it's either a Link or it's the end of the list: data List a = Link a (List a) | Nil You could do this in C++ with two different classes inheriting from a common base class, and then use RTTI to discover what variant of List something is, or add a virtual function called isLink or something, or maybe just have a single variant but add a boolean or an enum field describing wether or not the Link pointer is valid. As you see it gets messy (and in this trivial case you would use the built in two-way case of pointers, where you can specify Nil as simply a link with a null tail - but that's not always the possible, and even in this case I find it much nicer to explicitly use two completely different representations for the two variants). In general you don't tend to use this sort of tagged union to build stuff in OOP so there's no direct correspondence to typical OOP patterns. So one side effect of learning Haskell is (or at least was to me) a greater familiarity with that approach to describing data, which is simple and powerful enough that you sometimes emulate it even when it gets a bit messy in other languages. It really gets nice when you start defining functions on the data type using pattern matching, as everything is just extremely clear and nice since you only deal with one case at a time.. Here's a few examples using the list (uncompiled): isEmpty Nil = True isEmpty _ = False length Nil = 0 length (Link _ xs) = 1 + length xs concat Nil xs = xs concat (Link x xs) ys = Link x (concat xs ys) -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Ahhh I'll give it a read. thanks -Original Message- From: Henning Thielemann [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 13:05 To: Nicholls, Mark Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On Mon, 17 Dec 2007, Nicholls, Mark wrote: After many years of OOP though my brain is wired up to construct software in that 'pattern'a problem for me at the moment is I cannot see how to construct programs in an OO style in HaskellI know this is probably not the way to approach it...but I feel I need to master the syntax before the paradigm. This issue is rather a FAQ. Let's look what our Wiki provides: http://www.haskell.org/haskellwiki/OOP_vs_type_classes ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] data vs newtype (was: OOP'er with (hopefully) trivial questions)
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Nicholls, Mark To recap... type introduces a synonym for another type, no new type is createdit's for readabilities sake. Newtype introduces an isomorphic copy of an existing type...but doesn't copy it's type class membership...the types are disjoint/distinct but isomorphic (thus only 1 constructor param). data introduces a new type, and defines a composition of existing types to create a new one based on - and (. class introduces a constraint that any types declaring themselves to be a member of this class...that functions must exist to satisfy the constraint. As an aside, I was wondering exactly what the differences are between newtype and data i.e. between newtype A a = A a and data A a = A a According to: http://www.haskell.org/onlinereport/decls.html#sect4.2.3 newtype is, umm, stricter than data i.e. newtype A undefined = undefined, but data A undefined = A undefined. Other than that, newtype just seems to be an optimization hint. Is that a more-or-less correct interpretation? Alistair * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: data vs newtype (was: OOP'er with (hopefully) trivial questions)
From: Bayley, Alistair newtype A a = A a and data A a = A a Sorry, that should read: newtype A = A a data A = A a * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] RE: data vs newtype (was: OOP'er with (hopefully)trivial questions)
From: Bayley, Alistair Sorry, that should read: newtype A = A a data A = A a Ignore that; I was right first time. Sorry 'bout the spam, and the lack of brain. * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Monads that are Comonads and the role of Adjunction
On Dec 17, 2007 4:34 AM, Yitzchak Gale [EMAIL PROTECTED] wrote: Derek Elkins wrote: There is another very closely related adjunction that is less often mentioned. ((-)-C)^op -| (-)-C or a - b - C ~ b - a - C This gives rise to the monad, M a = (a - C) - C this is also exactly the comonad it gives rise to (in the op category which ends up being the above monad in the normal category). That looks very like the type of mfix. Is this related to MonadFix? I think that's the continuation monad. -- Dave Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Yampa / AFRPVectorSpace.hs
Certainly looks like a typo to me! Peter Verswyvelen wrote: While studying the vector space class in AFRP, I encountered the following strange code: class Floating a = VectorSpace v a | v - a where ... v1 ^-^ v2 = v1 ^+^ v1 -- (negateVector v2) I have no idea why the (negateVector v2) has been commented out, but surely this must be a typo? Cheers, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
On Dec 17, 2007 8:18 AM, Nicholls, Mark [EMAIL PROTECTED] wrote: The approach is deliberate...but I accept may be harder than it needs to be...I'm interested in Haskell because of the alleged power/formality of it's type system against the relatively weakness of OO ones...the irony at the moment is that they do not really seem to correspond directlyand OO type system seems to (loosely) correlate to Haskell type class system, and an OO class system (loosely) to Haskels type system, though in OOP's they are unpleasantly tangled. When I was learning Haskell, I found it helpful to think this way: In an OO system, classes describe objects. In Haskell, classes decribe types. It may also be helpful to note that Haskell's class system can be emulated in the language itself[1] by a technique known as dictionary passing. For example, the Eq class is equivalent to a function of type a - a - Bool, for some a. type EqD a = a - a - Bool So any time I have a function that uses Eq, foo :: Eq a = a - a - a - a foo a b c = if a == b then c else b I could define an equivalent function without it fooBy :: EqD a - a - a - a - a fooBy eq a b c = if eq a b then c else b The difference between foo and fooBy is that fooBy requires me to explicitly provide the Eq dictionary, whereas the compiler takes care of providing it to foo. A lot of functions in Data.List exist in foo and fooBy forms. [1] This isn't entirely true if we're talking about Haskell 98. Some classes dictionaries can't be defined without an extension, but that extension is widely supported and will almost certainly be in the next language standard. -- Dave Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Problem with a Win32 API
Dear all, When I run the program below a window appears for a split second, then disappears and the program exits. Can you help me figure out what's going wrong? *** import Graphics.Win32.Misc import Graphics.Win32.GDI.Types import Graphics.Win32.Window import System.Win32.DLL import Foreign.Marshal.Alloc main = do hInst - loadLibrary ole32.dll res - registerClass (style, hInst, Nothing, Nothing, Nothing, Nothing, classname) if res == Nothing then do{putStrLn Unable to register. ;return()} else putStrLn Registered. hwnd - createWindow classname Kleer 0 wS_VISIBLE Nothing Nothing Nothing Nothing Nothing Nothing hInst handler b - showWindow hwnd sW_SHOWNORMAL if b then putStrLn Window showing else do{putStrLn Unable to show window.; return()} updateWindow hwnd ptr - mallocBytes 4 getMessage ptr Nothing loop ptr loop msg = do translateMessage msg dispatchMessage msg loop msg handler :: WindowClosure handler hwnd msg w l = case msg of wM_CLOSE - do{destroyWindow hwnd; return 0} _ - defWindowProc (Just hwnd) msg w l style :: ClassStyle style = 0 classname = mkClassName KleerWnd *** E. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On Dec 17, 2007 8:04 AM, Nicholls, Mark [EMAIL PROTECTED] wrote: No that's fineits all as clear as mud!..but that's not your fault. To recap... type introduces a synonym for another type, no new type is createdit's for readabilities sake. Newtype introduces an isomorphic copy of an existing type...but doesn't copy it's type class membership...the types are disjoint/distinct but isomorphic (thus only 1 constructor param). data introduces a new type, and defines a composition of existing types to create a new one based on - and (. class introduces a constraint that any types declaring themselves to be a member of this class...that functions must exist to satisfy the constraint. I'm sure that's wrong, but it's a good as I've got at the moment. And to a degree it's all upside downwhat Haskell thinks are types...I think are singnatures and what Haskell thinks is a type class I think of as a type.it's not going to be easy. I think you've got it pretty well! The one quibble I would have with your recap is that I'm not sure what you mean by saying that data creates a new type 'based on - and ('. Other than that it seems pretty spot-on. =) -Brent ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] data vs newtype (was: OOP'er with (hopefully) trivial questions)
On Dec 17, 2007 8:51 AM, Bayley, Alistair [EMAIL PROTECTED] wrote: As an aside, I was wondering exactly what the differences are between newtype and data i.e. between newtype A a = A a and data A a = A a According to: http://www.haskell.org/onlinereport/decls.html#sect4.2.3 newtype is, umm, stricter than data i.e. newtype A undefined = undefined, but data A undefined = A undefined. Other than that, newtype just seems to be an optimization hint. Is that a more-or-less correct interpretation? Pretty much. Newtype is nice to have, but I don't think there's any program you can write that couldn't be rewritten to use data (with a possible loss of efficiency). The difference that surprised me is the difference between newtype A a = A a and data A a = A !a If we define a function like this, seqA (A a) = () Under the first definition of A, seqA undefined = () Under the second, seqA undefined = undefined The difference is that pattern-matching a newtype doesn't do any evaluation. -- Dave Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
No neither do II think we can drop that bitI think I got confused about it for a second.not unsurprisingly. From: Brent Yorgey [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 15:38 To: Nicholls, Mark Cc: Thomas Davie; Haskell Cafe Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. On Dec 17, 2007 8:04 AM, Nicholls, Mark [EMAIL PROTECTED] wrote: No that's fineits all as clear as mud!..but that's not your fault. To recap... type introduces a synonym for another type, no new type is createdit's for readabilities sake. Newtype introduces an isomorphic copy of an existing type...but doesn't copy it's type class membership...the types are disjoint/distinct but isomorphic (thus only 1 constructor param). data introduces a new type, and defines a composition of existing types to create a new one based on - and (. class introduces a constraint that any types declaring themselves to be a member of this class...that functions must exist to satisfy the constraint. I'm sure that's wrong, but it's a good as I've got at the moment. And to a degree it's all upside downwhat Haskell thinks are types...I think are singnatures and what Haskell thinks is a type class I think of as a type.it's not going to be easy. I think you've got it pretty well! The one quibble I would have with your recap is that I'm not sure what you mean by saying that data creates a new type 'based on - and ('. Other than that it seems pretty spot-on. =) -Brent ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Yampa / AFRPVectorSpace.hs
Hi Peter, Oops! Yes, as Paul says, clearly an error. My best guess is that it was commented out at some point for testing something, and then forgotten! The error does not occur in my local copy of the code, so a version skew problem to boot, I'm afraid. Best, /Henrik -- Henrik Nilsson School of Computer Science and Information Technology The University of Nottingham [EMAIL PROTECTED] This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Yampa / AFRPVectorSpace.hs
Maybe you could place Yampa in a Darcs depot? I will have some time now to study Yampa and apps again. To train myself, I would try to make a simple bouncing ball, then a Pong like game, and then I would like to convert the C++ minigames I made for my students. These might serve as simple tutorials for other people? After revision of course, because I'm a newbie, so you can expect some horrible Haskell code ;) Cheers, Peter -Original Message- From: Henrik Nilsson [mailto:[EMAIL PROTECTED] Sent: Monday, December 17, 2007 5:05 PM To: [EMAIL PROTECTED] Cc: Peter Verswyvelen; haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Yampa / AFRPVectorSpace.hs Hi Peter, Oops! Yes, as Paul says, clearly an error. My best guess is that it was commented out at some point for testing something, and then forgotten! The error does not occur in my local copy of the code, so a version skew problem to boot, I'm afraid. Best, /Henrik -- Henrik Nilsson School of Computer Science and Information Technology The University of Nottingham [EMAIL PROTECTED] This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Hello Mark, Monday, December 17, 2007, 4:47:50 PM, you wrote: I'll give it a read. http://www.haskell.org/haskellwiki/OOP_vs_type_classes i recommend you to read two papers mentioned in References section there. at least i'm one of this page authors and i don't think that i had very good understanding of type classes on the moment when this page was written. OTOH it also contains section written by John Meacham - it should be better because John is author of one Haskell compiler -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Am Montag, 17. Dezember 2007 13:04 schrieb Jed Brown: […] When your type only has one constructor, newtype is preferred over data, but they are semantically equivalent. They are *not* semantically equivalent, as has already been said more or less. data adds an extra level of indirection. With data A a = MkA a, _|_ (i.e., undefinedness) is different from MkA _|_. If I don’t know anything about a value of A a then this is not the same as knowing that the value is at least an application of MkA. newtype just creates wrapper types and it’s very unfortunate that it uses syntax similar to data because it’s very different. With newtype A a = MkA a, you just create a wrapper type A a for each type a. Applying the constructor just means casting from a to A a, and pattern matching just means casting from A a to a. Type-casting _|_ yields botton, that’s why MkA _|_ is _|_ and pattern matching _|_ against A x doesn’t fail but assigns _|_ to x. […] Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] #haskell works
Roman Leshchinskiy wrote: Andrew Coppin wrote: Then Mr C++ looked at it and said OMG! You don't *never* use strlen() inside a loop! and the second version was writting: Nice. I especially like the way it'll segfault if there is a blank at the end of the file. That's why I love C so much. :-) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: Re[2]: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
My Haskell is not up to understanding themI'm still writing hello world programswhat I read, gave me a good initial hint as to whats going on...I just need to get my Haskell going before I can jump in the deep end. -Original Message- From: Bulat Ziganshin [mailto:[EMAIL PROTECTED] Sent: 17 December 2007 16:37 To: Nicholls, Mark Cc: Henning Thielemann; haskell-cafe@haskell.org Subject: Re[2]: [Haskell-cafe] OOP'er with (hopefully) trivial questions. Hello Mark, Monday, December 17, 2007, 4:47:50 PM, you wrote: I'll give it a read. http://www.haskell.org/haskellwiki/OOP_vs_type_classes i recommend you to read two papers mentioned in References section there. at least i'm one of this page authors and i don't think that i had very good understanding of type classes on the moment when this page was written. OTOH it also contains section written by John Meacham - it should be better because John is author of one Haskell compiler -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Yampa / AFRPVectorSpace.hs
On Dec 17, 2007, at 4:30 PM, Peter Verswyvelen wrote: Maybe you could place Yampa in a Darcs depot? darcs get http://wagerlabs.com/yampa I think we should move it to Google Code, though. -- http://wagerlabs.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Yampa / AFRPVectorSpace.hs
joelr1: On Dec 17, 2007, at 4:30 PM, Peter Verswyvelen wrote: Maybe you could place Yampa in a Darcs depot? darcs get http://wagerlabs.com/yampa I think we should move it to Google Code, though. How about code.haskell.org ? Get yr accounts here, http://community.haskell.org/admin/ -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Very interesting, I did not know that! I thought newtype was an optimization of data, and that newtype was bad terminology. But if newtype is just a wrapper around a type, then the name is choosen well. I'm a bit confused why then one needs a data-constructor-like tag to construct a newtype value then? Is this to avoid having to add a type signature (for type inference)? I find this a bit weird since newtype Foo = Foo Int bar = Foo 123 does not safe a lot of keystrokes ;) compared to -- Incorrect Haskell follows newtype Foo = Int bar = 123::Foo -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Wolfgang Jeltsch Sent: Monday, December 17, 2007 5:39 PM To: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions. Am Montag, 17. Dezember 2007 13:04 schrieb Jed Brown: […] When your type only has one constructor, newtype is preferred over data, but they are semantically equivalent. They are *not* semantically equivalent, as has already been said more or less. data adds an extra level of indirection. With data A a = MkA a, _|_ (i.e., undefinedness) is different from MkA _|_. If I don’t know anything about a value of A a then this is not the same as knowing that the value is at least an application of MkA. newtype just creates wrapper types and it’s very unfortunate that it uses syntax similar to data because it’s very different. With newtype A a = MkA a, you just create a wrapper type A a for each type a. Applying the constructor just means casting from a to A a, and pattern matching just means casting from A a to a. Type-casting _|_ yields botton, that’s why MkA _|_ is _|_ and pattern matching _|_ against A x doesn’t fail but assigns _|_ to x. […] Best wishes, Wolfgang ___ 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] OOP'er with (hopefully) trivial questions.....
Thomas Davie [EMAIL PROTECTED] writes: Yes, and you can indeed do a similar thing in Haskell. The natural thing to do here would be to define a type Shape... data Shape = Circle Int | Rectangle Int Int | Square Int If however, you *really* want to keep your shapes as being seperate types, then you'll want to invoke the class system (note, not the same as OO classes). class Shape a where area :: a - Int newtype Circle = C Int instance Shape Circle where area (C r) = pi * r^2 There's a third way, too, and I haven't seen anybody mention it yet (apologies if I just missed it). You can provide an explicit record of the relevant member functions, and instantiate it in different ways. E.g. data Shape = Shape { area :: Int } square x = Shape (x^2) rectangle x y = Shape (x*y) circle r = Shape (pi*r^2) -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Peter Verswyvelen wrote: Very interesting, I did not know that! I thought newtype was an optimization of data, and that newtype was bad terminology. But if newtype is just a wrapper around a type, then the name is choosen well. I'm a bit confused why then one needs a data-constructor-like tag to construct a newtype value then? Is this to avoid having to add a type signature (for type inference)? I find this a bit weird since newtype Foo = Foo Int bar = Foo 123 does not safe a lot of keystrokes ;) compared to -- Incorrect Haskell follows newtype Foo = Int bar = 123::Foo You've broken the principle type property. let's stay away from numeric literals (which are fiddly because they're overloaded already in typeclass Num) and take a concrete type: data Foo = A | B newtype Bar = Bar Foo Now, the type of A is Foo. If I was allowed to write A::Bar then I no longer have a simple principle type for A: it appears that the type of A is Foo or Bar depending how I annotate it. Of course, I can make this work fine, using some form of constraint. Haskell already has constraints, we call them classes, and I could imagine giving A the principle type (FooOrNewtypeOfFoo a) = a However, that's a bunch of added complexity for such a simple feature :) Much nicer just to write A :: Foo and Bar A :: Bar. Jules ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
Thomas Davie wrote: Take a look at the Typable class. Although, pretty much any code that you can compile can be loaded into ghci without modification, and that's by far the easier way of finding the types of things. Is there a way to make ghci to know also the symbols which are not exported? My problem is that :t unexportedSymbolName reports undefined. Is there a way to make :t working without first exporting unexportedSymbolName and then reloading the module in ghci and asking with :t again? Peter. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] list utilities -- shouldn't these be in the hierarchical libs somewhere?
I found http://haskell.cs.yale.edu/haskell-report/List.html had many useful one off type list functions such as subsequences and permutations which are nowhere to be found in hoogle, Data.List, or the haskell hierarchical libs Shouldn't these be included somewhere? thomas. --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] data vs newtype (was: OOP'er with (hopefully) trivial questions)
On Mon, 2007-12-17 at 13:51 +, Bayley, Alistair wrote: From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Nicholls, Mark To recap... type introduces a synonym for another type, no new type is createdit's for readabilities sake. Newtype introduces an isomorphic copy of an existing type...but doesn't copy it's type class membership...the types are disjoint/distinct but isomorphic (thus only 1 constructor param). data introduces a new type, and defines a composition of existing types to create a new one based on - and (. class introduces a constraint that any types declaring themselves to be a member of this class...that functions must exist to satisfy the constraint. As an aside, I was wondering exactly what the differences are between newtype and data i.e. between newtype A a = A a and data A a = A a According to: http://www.haskell.org/onlinereport/decls.html#sect4.2.3 newtype is, umm, stricter than data i.e. newtype A undefined = undefined, but data A undefined = A undefined. Other than that, newtype just seems to be an optimization hint. Is that a more-or-less correct interpretation? More less than more. There is a context that can distinguish a newtype from a data type. This is explained on this wiki page that addresses exactly this question. http://www.haskell.org/haskellwiki/Newtype ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
A newtype can only have one constructor, with one argument, and is essentially a wrapper for that argument type. In the general case, you want to use data instead of newtype: data Rectangle = R Int Int I'm sure there's a trivial explanation for this, but here's something that I've always kind of wondered about: Given a single constructor type like data X = X A B C can't that be transformed into newtype X = X (A, B, C)? There must be some difference, because if there weren't we could transform all single constructor types that way, and dispense with newtype entirely. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
I'm sure there's a trivial explanation for this, but here's something that I've always kind of wondered about: Given a single constructor type like data X = X A B C can't that be transformed into newtype X = X (A, B, C)? There must be some difference, because if there weren't we could transform all single constructor types that way, and dispense with newtype entirely. Oops, nevermind, I just saw the other thread and link to http://www.haskell.org/haskellwiki/Newtype. Ok, so that seems like a pretty subtle diffenence... I'm assuming the rationale behind differentiating between a single constructor data and newtype is so that data types don't suddenly change their behaviour around undefined when they have only one constructor. I would find example y3 surprising if I came across it in real code! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 12/17/07, Evan Laforge [EMAIL PROTECTED] wrote: I'm sure there's a trivial explanation for this, but here's something that I've always kind of wondered about: Given a single constructor type like data X = X A B C can't that be transformed into newtype X = X (A, B, C)? There must be some difference, because if there weren't we could transform all single constructor types that way, and dispense with newtype entirely. Strictness. In newtype X = X A, the A field is strict. In data X = X A, the A field is lazy. So the compiler can't just turn all single-constructor data types into newtypes. (To generalize, if you were going to allow newtypes like newtype X = X (A, B, C), the tuple would be unboxed, and you'd have the same strictness/laziness distinction.) This is explained in section 4.2.3 of the H98 Report: http://www.haskell.org/onlinereport/decls.html Cheers, Tim -- Tim Chevalier * catamorphism.org * Often in error, never in doubt Do we learn from our mistakes? I surely hope not / Takes all the fun out of making them again.--Trout Fishing In America ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 12/17/07, Evan Laforge [EMAIL PROTECTED] wrote: Oops, nevermind, I just saw the other thread and link to http://www.haskell.org/haskellwiki/Newtype. Ok, so that seems like a pretty subtle diffenence... I'm assuming the rationale behind differentiating between a single constructor data and newtype is so that data types don't suddenly change their behaviour around undefined when they have only one constructor. I would find example y3 surprising if I came across it in real code! It's not that subtle if you think about what newtype is for. Newtype is like type, except that you're not just declaring a type synonym, but asking the typechecker to check that you don't use the synonym interchangeably with the type it's standing in for. Types declared with newtype and with type are supposed to act exactly the same way at runtime. In order to act exactly the same way at runtime, if you write newtype X = X A, X _|_ has to be indistinguishable from _|_ at runtime. In other words, the data constructor X has to be strict. In types declared with data, constructors are lazy -- if they weren't, you wouldn't be programming in Haskell. Cheers, Tim -- Tim Chevalier * catamorphism.org * Often in error, never in doubt People. Can't live with 'em, can't legally set fire to 'em. -- Sheree Schrager ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Monads that are Comonads and the role of Adjunction
On Mon, 2007-12-17 at 09:58 -0500, David Menendez wrote: On Dec 17, 2007 4:34 AM, Yitzchak Gale [EMAIL PROTECTED] wrote: Derek Elkins wrote: There is another very closely related adjunction that is less often mentioned. ((-)-C)^op -| (-)-C or a - b - C ~ b - a - C This gives rise to the monad, M a = (a - C) - C this is also exactly the comonad it gives rise to (in the op category which ends up being the above monad in the normal category). That looks very like the type of mfix. Is this related to MonadFix? I think that's the continuation monad. Let's do some (more) category theory. The unit of an adjunction (which is the unit of the monad it gives rise to) is the image of id in the isomorphism of hom-sets that defines an adjunction. In this case that isomorphism is (a - b - c) ~ (b - a - c), and the type completely determines the implementation (if you don't immediately recognize it), the isomorphism (in both ways actually) is flip. So the unit of the adjunction (return) is flip id and indeed that is exactly what Cont's definition of return is. (a - C) is a contravariant functor in a, so class ContraFunctor f where cofmap :: (b - a) - f a - f b instance ContraFunctor (- c) where -- not legal cofmap f = (. f) This obviously satisfies the (contravariant) functor laws, cofmap id = id and cofmap (f . g) = cofmap g . cofmap f instance Functor M where fmap = cofmap . cofmap This obviously satisfies the functor laws, fmap id = id and fmap (f . g) = fmap f . fmap g join is then join :: M (M a) - M a join = cofmap (flip id) -- flip id is also the counit This implementation is also forced by the types. (=) then has it's standard definition in terms of join and fmap, m = f = join (fmap f m) and if this is expanded out, this is indeed seen to be the implementation of (=) for the continuation monad. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
There was a thread about this recently. In any case, if you load the code interpreted (which happens if there is no .o or .hi file of the module lying around), then you can look inside all you want. But if it loads compiled, then you only have access to the exported symbols. The reason is because of inlining optimizations; you know about the encapsulation of the module when you compile it, and you can optimize the memory and code usage based on compiling functions that are not exported differently. That's my weak understanding, at least. Luke On Dec 17, 2007 5:52 PM, Peter Hercek [EMAIL PROTECTED] wrote: Thomas Davie wrote: Take a look at the Typable class. Although, pretty much any code that you can compile can be loaded into ghci without modification, and that's by far the easier way of finding the types of things. Is there a way to make ghci to know also the symbols which are not exported? My problem is that :t unexportedSymbolName reports undefined. Is there a way to make :t working without first exporting unexportedSymbolName and then reloading the module in ghci and asking with :t again? Peter. ___ 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] OOP'er with (hopefully) trivial questions.....
Am Montag, 17. Dezember 2007 19:26 schrieb Tim Chevalier: On 12/17/07, Evan Laforge [EMAIL PROTECTED] wrote: I'm sure there's a trivial explanation for this, but here's something that I've always kind of wondered about: Given a single constructor type like data X = X A B C can't that be transformed into newtype X = X (A, B, C)? There must be some difference, because if there weren't we could transform all single constructor types that way, and dispense with newtype entirely. Strictness. In newtype X = X A, the A field is strict. In data X = X A, the A field is lazy. So the compiler can't just turn all single-constructor data types into newtypes. Evan talked about data constructors with multiple fields, not with one single field. (To generalize, if you were going to allow newtypes like newtype X = X (A, B, C), the tuple would be unboxed, and you'd have the same strictness/laziness distinction.) This is not a generalization of what you talked about. Why should the tuple type be unboxed? Tuple types are boxed, meaning there is a difference between _|_ and (_|_,…,_|_). If you write newtype X = X (A, B, C) then X doesn’t add another level of indirection but the level of indirection introduced by the tuple constructor remains, of course. So you could write the above newtype declaration instead of data X = X A B C. _|_ would then be represented as X _|_ (equal to _|_) and X _|_ _|_ _|_ as X (_|_,_|_,_|_). Instead of pattern matching against X a b c, you would have to pattern match against X (a,b,c). So why not use the above newtype declaration instead of multi-field data declarations? One strong reason is that tuple types are itself algebraic data types which could be defined by data declarations if they wouldn’t use special syntax. So we would have to represent a tuple type by a newtype whose field type would be the tuple type we just want to represent. […] Cheers, Tim Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] gtk2hs treeview problem (Windows)
I installed ghc 6.6.1 and 0.9.12.1. I'm trying to use the tree view widget. To enable search in treeview, I added following 2 lines: New.treeViewAppendColumn view col3 -- my addition New.treeViewSetEnableSearch view True New.treeViewSetSearchColumn view 0 in demo/treeList/TreeDemo.hs The program crashes if I press any key. The console shows: C:\Gtk2Hs\demos\treeListTreeDemo.exe (TreeDemo.exe:3064): GLib-GObject-WARNING **: gtype.c:3339: type id `0' is inval id (TreeDemo.exe:3064): GLib-GObject-WARNING **: can't peek value table for type ` invalid' which is not currently referenced I also tried ghc 6.8.1 with the same result. Any hints? Thanks. Jian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On 12/17/07, Wolfgang Jeltsch [EMAIL PROTECTED] wrote: This is not a generalization of what you talked about. Why should the tuple type be unboxed? Tuple types are boxed, meaning there is a difference between _|_ and (_|_,…,_|_). If you write newtype X = X (A, B, C) then X doesn't add another level of indirection but the level of indirection introduced by the tuple constructor remains, of course. So you could write the above newtype declaration instead of data X = X A B C. I interpreted Evan's question as why can't you have newtypes with multiple fields? -- i.e., newtype X = X A B C -- and that's the question I was answering. But maybe I misunderstood. Cheers, Tim -- Tim Chevalier * catamorphism.org * Often in error, never in doubt After three days without programming, life becomes meaningless. -- James Geoffrey ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
There's a third way, too, and I haven't seen anybody mention it yet I've noticed it, but there are some problems with this representation, so I decided not to mention it. It's OK as far as we don't want functions working on two areas - I don't see, how we can implement, say, intersect :: Shape - Shape - Bool in this way. However, it's a useful pattern. (apologies if I just missed it). You can provide an explicit record of the relevant member functions, and instantiate it in different ways. E.g. data Shape = Shape { area :: Int } square x = Shape (x^2) rectangle x y = Shape (x*y) circle r = Shape (pi*r^2) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Is StateT what I need?
Hello (Newbie question ahead :) I'm trying to write a program which will build a tree (here represented as a Map) of unix processes. The tree should be built by reading the process information stored in /proc/PID/status. There is also another Map which will be used for faster insertions on the process tree, which I'd like to handle as my program state. So far I have the functions to get a list of entries from /proc, filter the ones that represent processes and get the information from their status file. Now I need an insertProc function, which should get the information for a given process ID, update the state and return that information. This is where I think I need StateT, but I couldn't find out how to use it (never used StateT before...). This is what I have so far: type Pid = FilePath type Uid = String type PsData = Map String Uid type PsChildren = Map Pid PsInfo data PsInfo = PsInfo PsData PsChildren type PsMap = Map Pid PsInfo type PsTree = Map Pid PsInfo parent :: PsData - Pid parent psData = fromJust $ Map.lookup PPid psData getProcInfo :: PsData - String - IO PsData getProcInfo psData line = do case matchRegex (mkRegex ^([a-z]+):[[:space:]]+(.*)$) line of Nothing - return (psData) Just [key, value] - return (Map.insert key value psData) procInfo :: Pid - IO PsInfo procInfo pid = do procData - readFile $ /proc/ ++ pid ++ /status psData - foldM getProcInfo Map.empty (lines procData) let [rUid, eUid, _] = words $ fromJust (Map.lookup Uid psData) let [rGid, eGid, _] = words $ fromJust (Map.lookup Gid psData) let uids = Map.fromList [(RUid, rUid), (EUid, eUid), (RGid, rGid), (EGid, eGid)] let psData' = Map.union psData uids return (PsInfo psData' Map.empty) I tried this for insertProc, but it obviously doesn't work... what would be the correct way to do this? insertProc :: Pid - StateT PsMap IO PsInfo insertProc pid = do proc - procInfo pid -- XXX this is obviously wrong... psMap - get put (Map.insert pid proc psMap) return (proc) A second question: is it possible to make getProcInfo's type to be PsData - String - PsData and use some operation similar to lift so that it can be used with foldM, instead of making its return type to be IO PsData explicitely? Thanks in advance, Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Questions about the Functor class and it's use in Data types à la carte
Excellent! This has all been very helpful. Thanks a lot everybody! :-) -Corey On 12/14/07, Benja Fallenstein [EMAIL PROTECTED] wrote: Hi Corey, On Dec 14, 2007 8:44 PM, Corey O'Connor [EMAIL PROTECTED] wrote: The reason I find all this odd is because I'm not sure how the type class Functor relates to the category theory concept of a functor. How does declaring a type constructor to be an instance of the Functor class relate to a functor? Is the type constructor considered a functor? Recall the definition of functor. From Wikipedia: A functor F from C to D is a mapping that * associates to each object X in C an object F(X) in D, * associates to each morphism f:X - Y in C a morphism F(f):F(X) - F(Y) in D such that the following two properties hold: * F(idX) = idF(X) for every object X in C * F(g . f) = F(g) . F(f) for all morphisms f:X - Y and g:Y - Z. http://en.wikipedia.org/wiki/Functor We consider C = D = the category of types. Note that any type constructor is a mapping from types to types -- thus it associates to each object (type) X an object (type) F(X). Declaring a type constructor to be an instance of Functor means that you have to provide 'fmap :: (a - b) - (f a - f b) -- that is, a mapping that associates to each morphism (function) fn :: a - b a morphism fmap fn :: f a - f b. Making sure that the two laws are fulfilled is the responsibility of the programmer writing the instance of Functor. (I.e., you're not supposed to do this: instance Functor Val where fmap f (Val x) = Val (x+1).) Hope this helps with seeing the correspondence? :-) - Benja -- -Corey O'Connor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: OOP'er with (hopefully) trivial questions.....
Luke Palmer wrote: There was a thread about this recently. In any case, if you load the code interpreted (which happens if there is no .o or .hi file of the module lying around), then you can look inside all you want. But if it loads compiled, then you only have access to the exported symbols. The reason is because of inlining optimizations; you know about the encapsulation of the module when you compile it, and you can optimize the memory and code usage based on compiling functions that are not exported differently. That's my weak understanding, at least. Luke Great. Cleaning before loading into ghci works. Thanks, Peter. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
I interpreted Evan's question as why can't you have newtypes with multiple fields? -- i.e., newtype X = X A B C -- and that's the question I was answering. But maybe I misunderstood. Well, the question was both, and strictness answers both. Thanks for the clarification. I should have realized that of course (,) is an ADT just like all the rest. I guess that means that 'data X = X Y Z' is always preferable to 'newtype X = X (Y, Z)' since the latter is just like the former but with some extra typing. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Is StateT what I need?
Andre Nathan wrote: Hello (Newbie question ahead : I tried this for insertProc, but it obviously doesn't work... what would be the correct way to do this? insertProc :: Pid - StateT PsMap IO PsInfo insertProc pid = do proc - procInfo pid -- XXX this is obviously wrong... psMap - get put (Map.insert pid proc psMap) return (proc) I see that using lift makes it compile (Control.Monad.Trans.lift): insertProc pid = do proc - lift (procInfo pid) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Compiling GLFW / SOE on Windows
Hi, This might be a tip for people trying to compile the GLFW package bundled with SOE on Windows. I had to because I slightly modified the GLFW source code. The SOE readme.txt says: For Win32 users, you'll need MinGW environment to compile GLFW. If make win32-mgw is unable to execute compile.bat propperly, use compile.bat mgw. Please also make sure that your MinGW path should come before the GHC's gcc-lib path in the PATH environment. However, the readme.html file has the following note: Do not use the MSYS shell for compiling GLFW, because the supplied batch file compile.bat will only work under a Windows command prompt (or MS-DOS prompt). To get it working, I basically needed to modify my PATH environment variable so that it contains the MSYS bin folder (in my case C:\app\msys\1.0\bin), and then run COMPILE.bat make mgw file using the Windows command prompt (CMD.EXE) instead of the MSYS unix shell emulator... Cheers, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Dec 17, 2007, at 14:33 , Andre Nathan wrote: insertProc :: Pid - StateT PsMap IO PsInfo insertProc pid = do proc - procInfo pid -- XXX this is obviously wrong... proc - lift $ procInfo pid psMap - get put (Map.insert pid proc psMap) modify (Map.insert pid proc) -- same as the above but cleaner return (proc) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Compiling GLFW / SOE on Windows
Ø However, the readme.html file has the following note: That should have been the GLFW readme.html file PS: Why do I always see these errors *after* I already posted to the forum? ;) This is actually one advantage of web-based forums, you can always edit the original message J From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Peter Verswyvelen Sent: Monday, December 17, 2007 9:30 PM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Compiling GLFW / SOE on Windows Hi, This might be a tip for people trying to compile the GLFW package bundled with SOE on Windows. I had to because I slightly modified the GLFW source code. The SOE readme.txt says: For Win32 users, you'll need MinGW environment to compile GLFW. If make win32-mgw is unable to execute compile.bat propperly, use compile.bat mgw. Please also make sure that your MinGW path should come before the GHC's gcc-lib path in the PATH environment. However, the readme.html file has the following note: Do not use the MSYS shell for compiling GLFW, because the supplied batch file compile.bat will only work under a Windows command prompt (or MS-DOS prompt). To get it working, I basically needed to modify my PATH environment variable so that it contains the MSYS bin folder (in my case C:\app\msys\1.0\bin), and then run COMPILE.bat make mgw file using the Windows command prompt (CMD.EXE) instead of the MSYS unix shell emulator... Cheers, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Is StateT what I need?
Am Montag, 17. Dezember 2007 21:06 schrieb ChrisK: Andre Nathan wrote: Hello (Newbie question ahead : I tried this for insertProc, but it obviously doesn't work... what would be the correct way to do this? insertProc :: Pid - StateT PsMap IO PsInfo insertProc pid = do proc - procInfo pid -- XXX this is obviously wrong... psMap - get put (Map.insert pid proc psMap) return (proc) I see that using lift makes it compile (Control.Monad.Trans.lift): insertProc pid = do proc - lift (procInfo pid) By the way, be careful with identifiers named “proc”. There is a syntax extension (arrow notation) which introduces a new keyword “proc”. Best wishes, Wolfgang ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
This is what I have so far: type Pid = FilePath type Uid = String type PsData = Map String Uid type PsChildren = Map Pid PsInfo data PsInfo = PsInfo PsData PsChildren type PsMap = Map Pid PsInfo type PsTree = Map Pid PsInfo parent :: PsData - Pid parent psData = fromJust $ Map.lookup PPid psData getProcInfo :: PsData - String - IO PsData getProcInfo psData line = do case matchRegex (mkRegex ^([a-z]+):[[:space:]]+(.*)$) line of Nothing - return (psData) Just [key, value] - return (Map.insert key value psData) procInfo :: Pid - IO PsInfo procInfo pid = do procData - readFile $ /proc/ ++ pid ++ /status psData - foldM getProcInfo Map.empty (lines procData) let [rUid, eUid, _] = words $ fromJust (Map.lookup Uid psData) let [rGid, eGid, _] = words $ fromJust (Map.lookup Gid psData) let uids = Map.fromList [(RUid, rUid), (EUid, eUid), (RGid, rGid), (EGid, eGid)] let psData' = Map.union psData uids return (PsInfo psData' Map.empty) I tried this for insertProc, but it obviously doesn't work... what would be the correct way to do this? insertProc :: Pid - StateT PsMap IO PsInfo insertProc pid = do proc - procInfo pid -- XXX this is obviously wrong... psMap - get put (Map.insert pid proc psMap) return (proc) A second question: is it possible to make getProcInfo's type to be PsData - String - PsData and use some operation similar to lift so that it can be used with foldM, instead of making its return type to be IO PsData explicitely? Yes, and in fact, you don't even need foldM. The only thing that actually uses IO is the readFile, so ideally you should just have a small function that just does the readFile and then processes the result using some (pure) functions. Something like this: procInfo :: Pid - IO PsInfo procInfo pid = do procData - readFile $ /proc/ ++ pid ++ /status return $ processData procData processData :: String - PsInfo ... and so on ... and so on. Now instead of using foldM you can just use foldr. IO is a cancer, best to keep it confined to as little of your program as possible! =) -Brent ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Dec 17, 2007, at 15:41 , Brent Yorgey wrote: Yes, and in fact, you don't even need foldM. The only thing that actually uses IO is the readFile, so ideally Actually, a quick check indicates that the regex functions used in getProcInfo are in IO as well (?!). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Mon, 17 Dec 2007 16:04:24 -0500 Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On Dec 17, 2007, at 15:41 , Brent Yorgey wrote: Yes, and in fact, you don't even need foldM. The only thing that actually uses IO is the readFile, so ideally Actually, a quick check indicates that the regex functions used in getProcInfo are in IO as well (?!). That's because they're implemented in C, and anything implemented in C is potentially impure. Although, I'd have thought that they'd *actually* be pure. -- Robin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Dec 17, 2007 1:04 PM, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote: On Dec 17, 2007, at 15:41 , Brent Yorgey wrote: Yes, and in fact, you don't even need foldM. The only thing that actually uses IO is the readFile, so ideally Actually, a quick check indicates that the regex functions used in getProcInfo are in IO as well (?!). Those functions look pure to me: GHCi, version 6.8.1: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Prelude :m +Text.Regex Prelude Text.Regex :t matchRegex . mkRegex matchRegex . mkRegex :: String - String - Maybe [String] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
On Mon, 2007-12-17 at 22:12 +0300, Miguel Mitrofanov wrote: There's a third way, too, and I haven't seen anybody mention it yet I've noticed it, but there are some problems with this representation, so I decided not to mention it. It's OK as far as we don't want functions working on two areas - I don't see, how we can implement, say, intersect :: Shape - Shape - Bool in this way. However, it's a useful pattern. And how do you do it in a typical OO language like Java or C# or Smalltalk? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Mon, 2007-12-17 at 17:33 -0200, Andre Nathan wrote: Hello (Newbie question ahead :) Thanks everyone for the great suggestions. The code is much cleaner now (not to mention it works :) This is the first non-tutorial program I'm writing and all this monad stuff is easier than I thought it would be. I think newbies like me tend to get scared after reading all those monad tutorials and maybe give up before actually trying to use them, and don't realize they're more like... I don't know... warm fuzzy things? ;) [I'm talking about my own experience here... I've given up many times while trying to learn all this, but at least this time it seems to be working better.] Thanks again, Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OOP'er with (hopefully) trivial questions.....
Miguel Mitrofanov [EMAIL PROTECTED] writes: I've noticed it, but there are some problems with this representation, so I decided not to mention it. It's OK as far as we don't want functions working on two areas - I don't see, how we can implement, say, intersect :: Shape - Shape - Bool in this way. However, it's a useful pattern. Yes, there are different trade offs, it depends what you want to do. The AlgDT makes intersect simple: intersect :: Shape - Shape - Bool intersect (Circle x) (Circle y) = ... intersect (Circle x) (Rectangle x y) = ... : As Derek hints at, this isn't so nice in C++ and friends, you probably will end up with // Apologies for any mistakes in the code, it's been a while. class Circle : public Shape { : bool intersect(s){ if(dynamic_castCircle(s)){...} else if (dynamic_castRectangle(s)){...} : } } etc. In addition to being very verbose and tedious code to write, you will have no idea if you have managed to cover all cases. Your 'intersect' function is spread all over the place. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Anyone mind proofing a short monad transformers explanation?
I sent this to a friend who asked me about monad transformers and he reckons it should be saved somewhere. If anyone feels up to giving it a quick fact-check, that'd be great. I'm not sure what to do with it, though. It doesn't seem to be made of the right stuff for a tutorial but I'm not sure what to do with it. --- SNIP --- Basically it's like making a double, triple, quadruple, ... monad by wrapping around existing monads that provide wanted functionality. You have an innermost monad (usually Identity or IO but you can use any monad). You then wrap monad transformers around this monad to make bigger, better monads. Concrete example: Suppose I was writing a server. Each client thread must be of type IO () (that's because forkIO :: IO () - IO ThreadID)). Suppose also that this server has some configuration that (in an imperative program) would be global that the clients all need to query. data Config = Config Foo Bar Baz One way of doing this is to use currying and making all the client threads of type Config - IO (). Not too nice because any functions they call have to be passed the Config parameter manually. The Reader monad solves this problem but we've already got one monad. We need to wrap IO in a ReaderT. The type constructor for ReaderT is ReaderT r m a, with r the shared environment to read from, m the inner monad and a the return type. Our client_func becomes: client_func :: ReaderT Config IO () We can then use the ask, asks and local functions as if Reader was the only Monad: (these examples are inside do blocks) p - asks port (Assuming some function port :: Config - Int or similar.) To do stuff in IO (or in the general case any inner monad) the liftIO function is used to make an IO function work in this wrapped space: (given h :: Handle, the client's handle) liftIO $ hPutStrLn h You lose liftIO $ hFlush h IO is once again special. For other inner monads, the lift function does the same thing. Note also that IO has no transformer and must therefore always be the innermost monad. This is all well and good, but the client_func now has type ReaderT Config IO () and forkIO needs a function of type IO (). The escape function for Reader is runReader :: Reader r a - r - a and similarly for ReaderT the escape function is runReaderT :: ReaderT r m a - r - m a: (Given some c :: Config that's been assembled from config files or the like) forkIO (runReaderT client_func c) Will do the trick. Monad transformers are like onions. They make you cry but you learn to appreciate them. Like onions, they're also made of layers. Each layer is the functionality of a new monad, you lift monadic functions to get into the inner monads and you have transformerised functions to unwrap each layer. They're also like a present in that regard: in this example we unwrapped the outer wrapping paper to get to the present: an object of type IO (), which lets us make haskell do something. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Mon, 2007-12-17 at 21:22 -0200, Andre Nathan wrote: On Mon, 2007-12-17 at 17:33 -0200, Andre Nathan wrote: Hello (Newbie question ahead :) Thanks everyone for the great suggestions. The code is much cleaner now (not to mention it works :) This is the first non-tutorial program I'm writing and all this monad stuff is easier than I thought it would be. I think newbies like me tend to get scared after reading all those monad tutorials and maybe give up before actually trying to use them, and don't realize they're more like... I don't know... warm fuzzy things? ;) [I'm talking about my own experience here... I've given up many times while trying to learn all this, but at least this time it seems to be working better.] Have you read Wadler's papers? http://homepages.inf.ed.ac.uk/wadler/topics/monads.html In particular one of The essence of functional programming or Monads for Functional Programming? If not, I think you'll find them better in every way* than any tutorial despite being written 15 years ago. * And I do mean -every- way; they are also more entertaining and easier to read. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: announcing darcs 2.0.0pre2
Thanks for the timings. Alas, I'm leaving in the morning for vacation, so I'm not sure when I'll have time to profile these operations. And I'm still puzzling over how to speed up darcs get (i.e. the long discussion of http pipelining, which will not, of course, do anything to help the poor folks stuck with ssh...). The 100x slower pull is indeed a bit puzzling. I can't help but wonder if it's the hash-checking (but that seems very unlikely)... David On Mon, Dec 17, 2007 at 12:29:20PM +, Simon Marlow wrote: Continuing my performance tests, I tried unpulling and re-pulling a bunch of patches in a GHC tree. I'm unpulling about 400 patches using --from-tag, and then pulling them again from a local repo. Summary: darcs2 is about 10x slower than darcs1 on unpull, and on pull it is 100x slower in user time but only 20x slower in elapsed time. In both cases, the repository was on an NFS filesystem. In the darcs2 case, the repository I was pulling from was on the local disk, and I'm also using a cache (NFS-mounted). The darcs2 repository has been optimized, but the darcs1 repository has not (at lesat, not recently). I did all of these a couple of times to eliminate the effects of cache preloading etc., the times reported are from the second run. --- darcs 1: $ time darcs unpull --from-tag 2007-09-25 -a Finished unpulling. 35.17s real 5.77s user 1.00s system 19% darcs unpull --from-tag 2007-09-25 -a $ time darcs pull ~/ghc-HEAD -a Pulling from /home/simonmar/ghc-HEAD... 33.51s real 3.62s user 1.05s system 13% darcs pull ~/ghc-HEAD -a --- darcs 2: $ time darcs2 unpull --from-tag 2007-09-25 -a Finished unpulling. 385.22s real 52.18s user 12.62s system 16% darcs2 unpull --from-tag 2007-09-25 -a $ time darcs2 pull /64playpen/simonmar/ghc-darcs2 -a Finished pulling and applying. 668.75s real 290.74s user 15.03s system 45% darcs2 pull /64playpen/simonmar/ghc-darcs2 -a -- David Roundy Department of Physics Oregon State University ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Anyone mind proofing a short monad transformers explanation?
On 12/17/07, Jack Kelly [EMAIL PROTECTED] wrote: liftIO $ hPutStrLn h You lose liftIO $ hFlush h IO is once again special. For other inner monads, the lift function does the same thing. Note also that IO has no transformer and must therefore always be the innermost monad. Actually, this isn't true. In the case of ReaderT Config IO (), liftIO is the same as lift. liftIO exists because it is more general; it works for any monad that is an instance of MonadIO, which includes IO, ReaderT r IO, StateT s IO, ReaderT r (StateT s (ErrorT e IO))), etc. In the last case, you could write lift $ lift $ lift $ hPutStrLn h You lose but it's much simpler to write liftIO $ hPutStrLn h You lose Similarily, ask is defined in the MonadReader typeclass, which includes Reader, ReaderT IO, and all sorts of other monads that include Reader at some level; only the real reader monad has a full implementation; the rest are defined in terms of lift or simpler operations, like so: instance MonadReader r m = MonadReader r (StateT s m) where ask = lift ask local f m = StateT $ \s - local f (runStateT m s) -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is StateT what I need?
On Mon, 2007-12-17 at 17:56 -0600, Derek Elkins wrote: Have you read Wadler's papers? Yeah, I read the two you mentioned. While I can't say I've already understood 100% of them, I completely agree with you in that they're the best texts on monads, from what I've seen (maybe because they explain so clearly why it is a good thing to have monads). You could have invented monads was good too, but I think those papers should be read first. Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] data vs newtype (was: OOP'er with (hopefully) trivial questions)
On 17 Dec 2007, at 7:39 AM, David Menendez wrote: On Dec 17, 2007 8:51 AM, Bayley, Alistair [EMAIL PROTECTED] wrote: As an aside, I was wondering exactly what the differences are between newtype and data i.e. between newtype A a = A a and data A a = A a According to: http://www.haskell.org/onlinereport/decls.html#sect4.2.3 newtype is, umm, stricter than data i.e. newtype A undefined = undefined, but data A undefined = A undefined. Other than that, newtype just seems to be an optimization hint. Is that a more-or-less correct interpretation? Pretty much. Newtype is nice to have, but I don't think there's any program you can write that couldn't be rewritten to use data (with a possible loss of efficiency). The difference that surprised me is the difference between newtype A a = A a and data A a = A !a If we define a function like this, seqA (A a) = () Under the first definition of A, seqA undefined = () Under the second, seqA undefined = undefined The difference is that pattern-matching a newtype doesn't do any evaluation. So there is a program (or, rather, type) you can write with newtype that can't be written with data: newtype T = T T jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] New to Haskell
A few days ago, for various reasons, I've started to look at Haskell. At first I was quite impressed, after reading some FAQ, and some tutorials. Evrything was nice and easy ... until I've started writing some code on my own. What I should have been told about upfront: - the syntax for an expression - the syntax for a block - the adhoc syntax rules (how to distinguish among a tuple and a pharanthesized expression and how to find the start and end of a block for example ) - the fact that lambda expressions are not the same thing as algebraic data values - what guarantees are made by the LANGUAGE that an IO action (such as do putStrLn Hello world ) is not performed twice - the lambda expressions can be written (input) but cannot be printed (output) The biggest problem for me, so far, is the last one. Here is some strange example: module Hugs where aa::Int aa=7 cc:: (Int-Int)-(Int-Int-Int)-Int-(Int-Int) cc a op b = \x- case x of { _ | x==aa - x+1 ; _- a x `op` b } f::Int-Int f(1)=1 f(2)=2 f(_)=3 g::Int-Int g(1)=13 g(2)=23 g(_)=33 h::[Int-Int] - Int -Int h [] x = x h [rr] x= let { u=Hugs.f ; v=Hugs.g } in case rr of { u - Hugs.g(x)+aa ; v - Hugs.f(x)+aa ; _ -rr (x) + aa } h (rr:ll) x = h [rr] x + h (ll) x What I don't understand is why I'm forced to use guards like x==aa in cc, when aa is clearly bounded (is 7) and why in function h, the bounded u and v become free variables in the case expression. Information from NOD32 This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe