From borgauf at gmail.com Thu Jul 1 16:41:21 2021 From: borgauf at gmail.com (Galaxy Being) Date: Thu, 1 Jul 2021 11:41:21 -0500 Subject: [Haskell-beginners] Date type needs helper function? Message-ID: I am using the built-in data type Day (Data.Time) in two ways data PDate = PDate Day or type PDate Day doesn't seem to matter. But then this doesn't work testrec1 = PDate 2021 7 1 I always must use the "helper function" fromGregorian testrec0 = PDate (fromGregorian 2021 7 1) ... PDate 2021-07-01 Looking at Real World Haskell examples data BookInfo = Book Int String [String] deriving (Show) ... myInfo = Book 9780135072455 "Algebra of Programming" ["Richard Bird", "Oege de Moor"] I know there's a great Haskell lesson to learn here, so why can Book take everything naked but my Day version not? ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From mlow at ualberta.ca Thu Jul 1 17:41:11 2021 From: mlow at ualberta.ca (Matthew Low) Date: Thu, 1 Jul 2021 11:41:11 -0600 Subject: [Haskell-beginners] Date type needs helper function? In-Reply-To: References: Message-ID: > why can Book take everything naked but my Day version not? The Day data type is actually just a newtype wrapper around an Int, which encodes the number of days since some point in the past - the docs more details: https://hackage.haskell.org/package/time-1.12/docs/Data-Time-Calendar.html. So to use the data constructor directly as in the Book example, you'd have to give it the number of days directly, something like ModifiedJulianDay 1234. The helper function gives a more convenient way to construct a Day. I believe this general approach of having functions to help you construct a data type is called 'smart constructors'. They're more common when the data constructors are not exported from a module, so the helper functions are the only way to create a value of that type - useful if you have some constraints you need enforced on your type. On Thu, Jul 1, 2021 at 10:41 AM Galaxy Being wrote: > I am using the built-in data type Day (Data.Time) in two ways > > data PDate = PDate Day > > or > > type PDate Day > > doesn't seem to matter. But then this doesn't work > > testrec1 = PDate 2021 7 1 > > I always must use the "helper function" fromGregorian > > testrec0 = PDate (fromGregorian 2021 7 1) > ... > PDate 2021-07-01 > > Looking at Real World Haskell examples > > data BookInfo = Book Int String [String] deriving (Show) > ... > myInfo = Book 9780135072455 "Algebra of Programming" ["Richard Bird", > "Oege de Moor"] > > I know there's a great Haskell lesson to learn here, so why can Book take > everything naked but my Day version not? > > > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Sat Jul 3 04:45:21 2021 From: borgauf at gmail.com (Galaxy Being) Date: Fri, 2 Jul 2021 23:45:21 -0500 Subject: [Haskell-beginners] Can't build project properly Message-ID: I'm trying to do a basic stack project named http-lesson (Chapter 39 from *Get Programming with Haskell) *which starts out with this in Main.hs module Main where import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Lazy.Char8 as LC import Network.HTTP.Simple After doing stack new http-lesson, the books says to modify the http-lesson.cabal file in the project, adding bytestring and http-conduit for the imports noted above executable http-lesson-exe main-is: Main.hs other-modules: Paths_http_lesson hs-source-dirs: app ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base >=4.7 && <5 , http-lesson , bytestring , http-conduit default-language: Haskell2010 Being a beginner, I follow the cookbook-like directions, i.e., I next run stack build . . . and it errors out, not finding the imported stuff. But then when I check the http-lesson.cabal file, the extra packages I added have been removed. Hunting around, I find this that tells me to put the extra packages in package.yaml. Very confused at this point. ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Sat Jul 3 21:57:54 2021 From: borgauf at gmail.com (Galaxy Being) Date: Sat, 3 Jul 2021 16:57:54 -0500 Subject: [Haskell-beginners] Can't build project properly In-Reply-To: References: Message-ID: Continue disregarding. Figured it out. Missing a language pragma. On Fri, Jul 2, 2021 at 11:45 PM Galaxy Being wrote: > I'm trying to do a basic stack project named http-lesson (Chapter 39 from *Get > Programming with Haskell) *which starts out with this in Main.hs > > module Main where > > import qualified Data.ByteString as B > import qualified Data.ByteString.Char8 as BC > import qualified Data.ByteString.Lazy as L > import qualified Data.ByteString.Lazy.Char8 as LC > import Network.HTTP.Simple > > After doing stack new http-lesson, the books says to modify the > http-lesson.cabal file in the project, adding bytestring and http-conduit for > the imports noted above > > executable http-lesson-exe > main-is: Main.hs > other-modules: > Paths_http_lesson > hs-source-dirs: > app > ghc-options: -threaded -rtsopts -with-rtsopts=-N > build-depends: > base >=4.7 && <5 > , http-lesson > , bytestring > , http-conduit > default-language: Haskell2010 > > Being a beginner, I follow the cookbook-like directions, i.e., I next run stack > build . . . and it errors out, not finding the imported stuff. But then > when I check the http-lesson.cabal file, the extra packages I added > have been removed. Hunting around, I find this > > that tells me to put the extra packages in package.yaml. Very confused at > this point. > > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > -- ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Tue Jul 20 20:42:45 2021 From: borgauf at gmail.com (Galaxy Being) Date: Tue, 20 Jul 2021 15:42:45 -0500 Subject: [Haskell-beginners] Ratio data constructor Message-ID: I'm investigating rational numbers with Haskell. This is the source I've found data Ratio a = !a :% !a deriving (Eq) reduce :: (Integral a) => a -> a -> Ratio a {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} reduce _ 0 = ratioZeroDenominatorError reduce x y = (x `quot` d) :% (y `quot` d) where d = gcd x y (%) :: (Integral a) => a -> a -> Ratio a x % y = reduce (x * signum y) (abs y) The Ratio data type would seem to be a parameterized type with two parameters of the same type that must be "settled" in that they're not to be lazily dealt with. Then the :% is the data constructor, the : meaning it's a data constructor and not just an operation function. So this could have been data Ratio a = :% !a !a deriving (Eq) correct? But then what confuses me is in reduce, why reduce x y = (x `quot` d) :% (y `quot` d) and not just %? We have :% defined in the data type and then (%) defined as a function. What is going on here? -- ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Tue Jul 20 21:16:55 2021 From: borgauf at gmail.com (Galaxy Being) Date: Tue, 20 Jul 2021 16:16:55 -0500 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: ... does the last question have to do with a "smart constructor" by chance? If so, how? On Tue, Jul 20, 2021 at 3:42 PM Galaxy Being wrote: > I'm investigating rational numbers with Haskell. This is the source I've > found > > data Ratio a = !a :% !a deriving (Eq) > > reduce :: (Integral a) => a -> a -> Ratio a > {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} > reduce _ 0 = ratioZeroDenominatorError > reduce x y = (x `quot` d) :% (y `quot` d) > where d = gcd x y > (%) :: (Integral a) => a -> a -> Ratio a > x % y = reduce (x * signum y) (abs y) > > The Ratio data type would seem to be a parameterized type with two > parameters of the same type that must be "settled" in that they're not to > be lazily dealt with. Then the :% is the data constructor, the : meaning > it's a data constructor and not just an operation function. So this could > have been > > data Ratio a = :% !a !a deriving (Eq) > > correct? But then what confuses me is in reduce, why > > reduce x y = (x `quot` d) :% (y `quot` d) > > and not just %? We have :% defined in the data type and then (%) defined > as a function. What is going on here? > > -- > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > -- ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Tue Jul 20 21:16:59 2021 From: bob at redivi.com (Bob Ippolito) Date: Tue, 20 Jul 2021 14:16:59 -0700 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: On Tue, Jul 20, 2021 at 1:43 PM Galaxy Being wrote: > I'm investigating rational numbers with Haskell. This is the source I've > found > > data Ratio a = !a :% !a deriving (Eq) > > reduce :: (Integral a) => a -> a -> Ratio a > {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} > reduce _ 0 = ratioZeroDenominatorError > reduce x y = (x `quot` d) :% (y `quot` d) > where d = gcd x y > (%) :: (Integral a) => a -> a -> Ratio a > x % y = reduce (x * signum y) (abs y) > > The Ratio data type would seem to be a parameterized type with two > parameters of the same type that must be "settled" in that they're not to > be lazily dealt with. Then the :% is the data constructor, the : meaning > it's a data constructor and not just an operation function. So this could > have been > The type has one parameter a, the (:%) constructor has two arguments (both of type a). > data Ratio a = :% !a !a deriving (Eq) > You always need to use parentheses around an infix operator to use it in prefix, just like you need backticks around a function to use it as infix (like `quot` in the implementation of reduce). data Ratio a = (:%) !a !a deriving (Eq) > correct? But then what confuses me is in reduce, why > > reduce x y = (x `quot` d) :% (y `quot` d) > > and not just %? We have :% defined in the data type and then (%) defined > as a function. What is going on here? > The function (%) uses reduce in its definition, the equation would never terminate due to infinite recursion if the function (%) was used instead of the constructor (:%). -bob -------------- next part -------------- An HTML attachment was scrubbed... URL: From toad3k at gmail.com Tue Jul 20 21:26:15 2021 From: toad3k at gmail.com (David McBride) Date: Tue, 20 Jul 2021 17:26:15 -0400 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: The Ratio type is a fraction. If a is Integer, it is an infinite precision fraction. You can divide it arbitrarily and it will never lose any precision (though it will take more space). Reduce is designed to create a fraction from two numbers, not solve it. so if you supply 5 and 10, it will return a Ratio 1/2, because 5 is the greatest common denominator. The % operator appears to take arbitrary numbers but it seems designed to intend to keep the negative sign on the numerator, so as to maintain some invariant in the data. On Tue, Jul 20, 2021 at 4:43 PM Galaxy Being wrote: > I'm investigating rational numbers with Haskell. This is the source I've > found > > data Ratio a = !a :% !a deriving (Eq) > > reduce :: (Integral a) => a -> a -> Ratio a > {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} > reduce _ 0 = ratioZeroDenominatorError > reduce x y = (x `quot` d) :% (y `quot` d) > where d = gcd x y > (%) :: (Integral a) => a -> a -> Ratio a > x % y = reduce (x * signum y) (abs y) > > The Ratio data type would seem to be a parameterized type with two > parameters of the same type that must be "settled" in that they're not to > be lazily dealt with. Then the :% is the data constructor, the : meaning > it's a data constructor and not just an operation function. So this could > have been > > data Ratio a = :% !a !a deriving (Eq) > > correct? But then what confuses me is in reduce, why > > reduce x y = (x `quot` d) :% (y `quot` d) > > and not just %? We have :% defined in the data type and then (%) defined > as a function. What is going on here? > > -- > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Tue Jul 20 21:36:41 2021 From: bob at redivi.com (Bob Ippolito) Date: Tue, 20 Jul 2021 14:36:41 -0700 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: Yes, the (%) function is a smart constructor for Data.Ratio because the (:%) constructor is not exported. Other examples of this smart constructor technique would be modules like Data.Set or Data.Map. A smart constructor means that the module that defines the type does not export its data constructor(s), making the implementation details opaque, generally because the author wanted to be able to make assumptions about the implementation that are not enforced by the type system. In this case, they wanted all Ratio to be in reduced form. This makes many operations faster or trivial, e.g. implementing Eq only requires comparing the numerators and denominators. More information about the technique is here: https://wiki.haskell.org/Smart_constructors On Tue, Jul 20, 2021 at 2:17 PM Galaxy Being wrote: > ... does the last question have to do with a "smart constructor" by > chance? If so, how? > > On Tue, Jul 20, 2021 at 3:42 PM Galaxy Being wrote: > >> I'm investigating rational numbers with Haskell. This is the source I've >> found >> >> data Ratio a = !a :% !a deriving (Eq) >> >> reduce :: (Integral a) => a -> a -> Ratio a >> {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} >> reduce _ 0 = ratioZeroDenominatorError >> reduce x y = (x `quot` d) :% (y `quot` d) >> where d = gcd x y >> (%) :: (Integral a) => a -> a -> Ratio a >> x % y = reduce (x * signum y) (abs y) >> >> The Ratio data type would seem to be a parameterized type with two >> parameters of the same type that must be "settled" in that they're not to >> be lazily dealt with. Then the :% is the data constructor, the : meaning >> it's a data constructor and not just an operation function. So this could >> have been >> >> data Ratio a = :% !a !a deriving (Eq) >> >> correct? But then what confuses me is in reduce, why >> >> reduce x y = (x `quot` d) :% (y `quot` d) >> >> and not just %? We have :% defined in the data type and then (%) defined >> as a function. What is going on here? >> >> -- >> ⨽ >> Lawrence Bottorff >> Grand Marais, MN, USA >> borgauf at gmail.com >> > > > -- > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Tue Jul 20 22:09:56 2021 From: borgauf at gmail.com (Galaxy Being) Date: Tue, 20 Jul 2021 17:09:56 -0500 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: Yes, I see here that the module Data.Ratio exports this module Data.Ratio ( Ratio, Rational, (%), numerator, denominator, approxRational ) where which doesn't include :%. But then I see numerator and denominator which do have :%. But then to use them, this, e.g., won't work numerator (60 20) It needs the % numerator (60 % 20) So internally, :% is used, but users can never use :%, only %, which sends things through reduce first. I could write my own version of Ratio that didn't hide : and that would be okay. Have I got this right? On Tue, Jul 20, 2021 at 4:37 PM Bob Ippolito wrote: > Yes, the (%) function is a smart constructor for Data.Ratio because the > (:%) constructor is not exported. Other examples of this smart constructor > technique would be modules like Data.Set or Data.Map. > > A smart constructor means that the module that defines the type does not > export its data constructor(s), making the implementation details > opaque, generally because the author wanted to be able to make assumptions > about the implementation that are not enforced by the type system. In this > case, they wanted all Ratio to be in reduced form. This makes many > operations faster or trivial, e.g. implementing Eq only requires comparing > the numerators and denominators. More information about the technique is > here: https://wiki.haskell.org/Smart_constructors > > > > On Tue, Jul 20, 2021 at 2:17 PM Galaxy Being wrote: > >> ... does the last question have to do with a "smart constructor" by >> chance? If so, how? >> >> On Tue, Jul 20, 2021 at 3:42 PM Galaxy Being wrote: >> >>> I'm investigating rational numbers with Haskell. This is the source I've >>> found >>> >>> data Ratio a = !a :% !a deriving (Eq) >>> >>> reduce :: (Integral a) => a -> a -> Ratio a >>> {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} >>> reduce _ 0 = ratioZeroDenominatorError >>> reduce x y = (x `quot` d) :% (y `quot` d) >>> where d = gcd x y >>> (%) :: (Integral a) => a -> a -> Ratio a >>> x % y = reduce (x * signum y) (abs y) >>> >>> The Ratio data type would seem to be a parameterized type with two >>> parameters of the same type that must be "settled" in that they're not to >>> be lazily dealt with. Then the :% is the data constructor, the : >>> meaning it's a data constructor and not just an operation function. So this >>> could have been >>> >>> data Ratio a = :% !a !a deriving (Eq) >>> >>> correct? But then what confuses me is in reduce, why >>> >>> reduce x y = (x `quot` d) :% (y `quot` d) >>> >>> and not just %? We have :% defined in the data type and then (%) >>> defined as a function. What is going on here? >>> >>> -- >>> ⨽ >>> Lawrence Bottorff >>> Grand Marais, MN, USA >>> borgauf at gmail.com >>> >> >> >> -- >> ⨽ >> Lawrence Bottorff >> Grand Marais, MN, USA >> borgauf at gmail.com >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Wed Jul 21 00:58:03 2021 From: bob at redivi.com (Bob Ippolito) Date: Tue, 20 Jul 2021 17:58:03 -0700 Subject: [Haskell-beginners] Ratio data constructor In-Reply-To: References: Message-ID: That sounds about right. numerator and denominator are deconstructors, which you need to use to access the fields because you can’t pattern match without access to the :% constructor. If you look at their implementation, they are deconstructing with a pattern match rather than constructing like the % function. On Tue, Jul 20, 2021 at 15:10 Galaxy Being wrote: > Yes, I see here > that > the module Data.Ratio exports this > > module Data.Ratio ( > Ratio, Rational, (%), numerator, denominator, approxRational ) where > > which doesn't include :%. But then I see numerator and denominator which > do have :%. But then to use them, this, e.g., won't work > > numerator (60 20) > > It needs the % > > numerator (60 % 20) > > So internally, :% is used, but users can never use :%, only %, which > sends things through reduce first. I could write my own version of Ratio > that didn't hide : and that would be okay. Have I got this > right? > > > > On Tue, Jul 20, 2021 at 4:37 PM Bob Ippolito wrote: > >> Yes, the (%) function is a smart constructor for Data.Ratio because the >> (:%) constructor is not exported. Other examples of this smart constructor >> technique would be modules like Data.Set or Data.Map. >> >> A smart constructor means that the module that defines the type does not >> export its data constructor(s), making the implementation details >> opaque, generally because the author wanted to be able to make assumptions >> about the implementation that are not enforced by the type system. In this >> case, they wanted all Ratio to be in reduced form. This makes many >> operations faster or trivial, e.g. implementing Eq only requires comparing >> the numerators and denominators. More information about the technique is >> here: https://wiki.haskell.org/Smart_constructors >> >> >> >> On Tue, Jul 20, 2021 at 2:17 PM Galaxy Being wrote: >> >>> ... does the last question have to do with a "smart constructor" by >>> chance? If so, how? >>> >>> On Tue, Jul 20, 2021 at 3:42 PM Galaxy Being wrote: >>> >>>> I'm investigating rational numbers with Haskell. This is the source >>>> I've found >>>> >>>> data Ratio a = !a :% !a deriving (Eq) >>>> >>>> reduce :: (Integral a) => a -> a -> Ratio a >>>> {-# SPECIALISE reduce :: Integer -> Integer -> Rational #-} >>>> reduce _ 0 = ratioZeroDenominatorError >>>> reduce x y = (x `quot` d) :% (y `quot` d) >>>> where d = gcd x y >>>> (%) :: (Integral a) => a -> a -> Ratio a >>>> x % y = reduce (x * signum y) (abs y) >>>> >>>> The Ratio data type would seem to be a parameterized type with two >>>> parameters of the same type that must be "settled" in that they're not to >>>> be lazily dealt with. Then the :% is the data constructor, the : >>>> meaning it's a data constructor and not just an operation function. So this >>>> could have been >>>> >>>> data Ratio a = :% !a !a deriving (Eq) >>>> >>>> correct? But then what confuses me is in reduce, why >>>> >>>> reduce x y = (x `quot` d) :% (y `quot` d) >>>> >>>> and not just %? We have :% defined in the data type and then (%) >>>> defined as a function. What is going on here? >>>> >>>> -- >>>> ⨽ >>>> Lawrence Bottorff >>>> Grand Marais, MN, USA >>>> borgauf at gmail.com >>>> >>> >>> >>> -- >>> ⨽ >>> Lawrence Bottorff >>> Grand Marais, MN, USA >>> borgauf at gmail.com >>> _______________________________________________ >>> Beginners mailing list >>> Beginners at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >>> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > > > -- > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From coot at coot.me Sat Jul 31 14:49:16 2021 From: coot at coot.me (coot at coot.me) Date: Sat, 31 Jul 2021 14:49:16 +0000 Subject: [Haskell-beginners] A one- or two-page diagram of how Haskell works? In-Reply-To: References: Message-ID: I recently wrote a blog post which explains how expressions are evaluated: https://coot.me/posts/containers-strict-foldr.html Best regards, Marcin Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Thursday, June 24th, 2021 at 05:41, Michael Turner wrote: > When I write C, or even C++, I have a mental model of how execution > > will proceed. > > When I write Prolog, but get confused, I run a kind of skeletal > > inference algorithm in my head and the confusion usually clears up. I > > can imagine how things are stored and what's done with them. I can see > > /through/ the code to the machine. > > With Haskell, I still feel blind. > > Has anyone summarized it all in a chart where I can look at it and > > think, "Ah, OK, GHC is taking this line and thinking of it THIS way"? > > If someone wanted to write an interpreter for Haskell, would there be > > a way for them to see how it would basically need to work, in one > > chart? > > Regards, > > Michael Turner > > Executive Director > > Project Persephone > > 1-25-33 Takadanobaba > > Shinjuku-ku Tokyo 169-0075 > > Mobile: +81 (90) 5203-8682 > > turner at projectpersephone.org > > Understand - http://www.projectpersephone.org/ > > Join - http://www.facebook.com/groups/ProjectPersephone/ > > Donate - http://www.patreon.com/ProjectPersephone > > Volunteer - https://github.com/ProjectPersephone > > "Love does not consist in gazing at each other, but in looking outward > > together in the same direction." -- Antoine de Saint-Exupéry > > Beginners mailing list > > Beginners at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 509 bytes Desc: OpenPGP digital signature URL: