On Sat, Jan 17, 2009 at 11:19 PM, Dan Piponi <[hidden email]> wrote:
> On Sat, Jan 17, 2009 at 1:47 AM, david48 <[hidden email]> wrote: >> why would I >> need to write a running count this way instead of, for example, a non >> monadic fold, which would probably result in clearer and faster code? > > Maybe my post here will answer some questions like that: > http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html Just wow. Very very nice post. one to keep in the wikis. Thank you *very* much, Dan, for writing this. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
On Sun, 18 Jan 2009 08:51:10 +0100
david48 <[hidden email]> wrote: > On Sat, Jan 17, 2009 at 11:19 PM, Dan Piponi <[hidden email]> > wrote: > > On Sat, Jan 17, 2009 at 1:47 AM, david48 > > <[hidden email]> wrote: > > >> why would I > >> need to write a running count this way instead of, for example, a > >> non monadic fold, which would probably result in clearer and > >> faster code? > > > > Maybe my post here will answer some questions like that: > > http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html > > Just wow. Very very nice post. one to keep in the wikis. > Thank you *very* much, Dan, for writing this. Seconded. And I hope, Dan, that you will find time at some point to write about those other things you said at the end that you didn't have time to write about! -- Robin _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Andrew Coppin
Andrew Coppin wrote:
>> instance (Monad m) => Functor m where >> fmap f ma = do a <- ma; return (f a) >> > > While that's quite interesting from a mathematical point of view, how is > this "useful" for programming purposes? Surely, you agree that liftM is "useful"? Because that's the same thing. Regards, apfelmus -- http://apfelmus.nfshost.com _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by John Lato-2
John Lato wrote:
> Here is the current complete documentation for Data.Monoid 'mappend', > which happens to be a good example of which I speak: > > An associative operation > > That could mean anything. There are lots of associative operations. Yes. In combination with the definition of mempty (the identity for mappend) that's exactly what a monoid is. I'm not (just) being flippant. This particular example actually highlights the limitations of type classes. There are, in fact, too many monoids. Too many to be able to define it based only on the carrier, i.e. the type that mempty belongs to and that mappend operates over. For example every (semi-)ring has at least two of them[1]. For more complicated mathematical structures there can be even more than that. This isn't to say that we should get rid of Monoid, just that using it can be... troublesome. But this has been mentioned already on a few other recent threads. The notion of appending only really applies to "the free monoid on a set A", aka strings of elements drawn from A. It bears highlighting that I said strings (in the mathematical sense) and not (linked) lists. The concatenation involved is mathematical juxtaposition, and the empty element is the empty string (which is subtly different than the empty list which is also used to terminate the datatype's recursion). These monoids are called free because they make no requirements on the underlying set, no requirements other than the monoid laws. All other monoids use some sort of structure in the underlying set in order to simplify expressions (e.g. 1+1 == 2, whereas a+a == aa). Because the free monoid doesn't simplify anything, all it does is append. [1] For example, Natural numbers: (Nat,+,0) (Nat,*,1) Boolean algebra: (Bool,or,False) (Bool,and,True) Bit-vector algebra: (Bits,bitOr,0) (Bits,bitAnd,-1) Any lattice L: (L,join,Bottom) (L,meet,Top) Any total ordering O: (O,max,NegativeInfinity) (O,min,Infinity) Any set universe U: (Power(U),union,EmptySet) (Power(U),intersection,U) ...let alone getting into fun things like the log-semiring, polynomials with natural coefficients, and so on. -- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Paul Moore-2
Paul Moore wrote:
> Apfelmus, Heinrich wrote: >> >> How to learn? The options are, in order of decreasing effectiveness >> >> university course teacher in person >> book irc >> mailing list >> online tutorial >> haskell wiki >> haddock documentation > > Reason by analogy from known/similar areas. I think the point here is > that for Haskell, this is more possible for mathematicians than for > programmers. And that's an imbalance that may need to be addressed > (depending on who you want to encourage to learn). > > But I agree that reasoning by analogy is not a very good way of > learning. And I think it's been established that the real issue here > is the documentation - complete explanations and better > discoverability[1] are needed. Yes, agreed. However, I would say that the word "documentation" does not apply anymore, it's more "subject of study". What I want to say is that to some extend, Haskell is not only similar to mathematics, it /is/ mathematics, so programmers have to learn mathematics. Traditionally, this is done in university courses or with books, I'm not sure whether learning mathematics via internet tutorials on the computer screen works. Regards, apfelmus -- http://apfelmus.nfshost.com _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Heinrich Apfelmus
Heinrich Apfelmus wrote:
> Andrew Coppin wrote: > >>> instance (Monad m) => Functor m where >>> fmap f ma = do a <- ma; return (f a) >>> >>> >> While that's quite interesting from a mathematical point of view, how is >> this "useful" for programming purposes? >> > > Surely, you agree that liftM is "useful"? Because that's the same thing. > Then why not just use liftM? (That way, you know what it does...) _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
Andrew Coppin wrote:
> Heinrich Apfelmus wrote: >> Andrew Coppin wrote: >> >>>> instance (Monad m) => Functor m where >>>> fmap f ma = do a <- ma; return (f a) >>>> >>> While that's quite interesting from a mathematical point of view, how is >>> this "useful" for programming purposes? >>> >> >> Surely, you agree that liftM is "useful"? Because that's the same >> thing. >> > > Then why not just use liftM? (That way, you know what it does...) liftM (*1) [1..10] = [2,4,6,8,10,12,14,16,18,20] Regards, apfelmus -- http://apfelmus.nfshost.com _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Ertugrul Söylemez
Ertugrul Soeylemez wrote:
> Andrew Coppin <[hidden email]> wrote: > > >> I would suggest that ExistentiallyQuantifiedTypeVariables would be an >> improvement [...] >> > > That must be a joke. Typing the long extension names in LANGUAGE > pragmas over and over again is tiring and annoying enough already. We > really don't need even longer names, and your "improvement" fills up > almost half of the width of an 80 characters terminal. > Which is why I personally prefer HiddenTypeVariables. (This has the advantage of using only pronouncible English words, which means you can use it when speaking out loud.) But, as I say, nobody is going to rename anything, so it's moot. > I can't await the next Haskell standard, where at last all those > extensions are builtin. This frightens me. At the moment, I understand how Haskell 98 works. There are lots of extensions out there, but I don't have to care about that because I don't use them. If I read somebody else's code and it contains a LANGUAGE pragma, I can immediately tell that the code won't be comprehendable, so I don't need to waste time trying to read it. But once Haskell' becomes standard, none of this holds any more. Haskell' code will use obscure lanuage features without warning, and unless I somehow learn every extension in the set, I'll never be able to read Haskell again! (One presumes that they won't add any extensions which actually *break* backwards compatibility, so hopefully I can still pretend these troublesome extensions don't exist when writing my own code...) _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Bugzilla from jonathanccast@fastmail.fm
Jonathan Cast wrote:
> On Sat, 2009-01-17 at 12:04 +0000, Andrew Coppin wrote: > >> >>> instance (Monad m) => Functor m where >>> fmap f ma = do a <- ma; return (f a) >>> >>> >> While that's quite interesting from a mathematical point of view, how is >> this "useful" for programming purposes? >> > > Good Lord. fmap (as above) is *at least* useful enough to be in the > standard library! (Control.Monad.liftM). Given that liftM exists, why is having an identical implementation for fmap useful? The example that leaps out at me is that (>>=) is identical to concatMap within the list monad. But using lists as a monad is a generally useful thing to do, and being able to substitute arbitrary monads has obvious utility. I'm not seeing how being able to treat something that isn't a container as if it was a container is useful. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
On Sun, Jan 18, 2009 at 3:23 AM, Andrew Coppin
<[hidden email]> wrote: > Given that liftM exists, why is having an identical implementation for fmap > useful? For many structures, it's easier to define (>>=) in terms of fmap and join. For these objects, often the "generic" implementation of liftM is far less efficient than fmap. That is to say, given a monad T and these functions: returnT :: a -> T a fmapT :: (a -> b) -> T a -> T b joinT :: T (T a) -> T a We can create Haskell instances as follows instance Functor T where fmap = fmapT instance Monad T where return = returnT m >>= f = joinT (fmap f m) Then, liftM f m = m >>= \x -> return (f x) = joinT (fmapT (\x -> return (f x)) m) Now, we know (by the monad & functor laws) that this is equivalent to (fmap f m), but it's a lot harder for the compiler to spot that. The list monad is a great example; I'd expect that using fmap (== map) in the list monad is significantly more efficient than liftM which constructs a singleton list for each element of the input and concatenates them all together. -- ryan _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by ajb@spamcop.net
On Sat, Jan 17, 2009 at 09:12:32PM -0500, [hidden email] wrote:
> And FWIW, I agree with everyone who has commented that the documentation > is inadequate. It'd be nice if there was some way to contribute better > documentation without needing checkin access to the libraries. There is. The current state of the docs may be viewed at http://www.haskell.org/ghc/dist/current/docs/libraries/ Anyone can check out the darcs repos for the libraries, and post suggested improvements to the documentation to [hidden email] (though you have to subscribe). It doesn't even have to be a patch. Sure, it could be smoother, but there's hardly a flood of contributions. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by David Leimbach
On Sat, 2009-01-17 at 13:36 -0800, David Leimbach wrote:
> > > On Sat, Jan 17, 2009 at 9:16 AM, david48 <[hidden email]> > wrote: > On Sat, Jan 17, 2009 at 4:08 PM, David Leimbach > <[hidden email]> wrote: > > > So you're saying it should be better documented in Haskell > what a Monoid is. > > Did you say you searched for "C++ class" why not "Haskell > Monoid" then? > > The first correct google hit that didn't think I meant > Monads, takes you > > straight to the GHC documentation for Data.Monoid. > > Read my first post on the thread, that's exactly what I did > ( and then > complained that the doc for Data.Monoid was close to useless ) > > > Sorry missed it! This is an exceptionally long thread! :-) I agree > Data.Monoid's docs don't give you much to work with. Do you think they look better now: http://www.haskell.org/ghc/dist/current/docs/libraries/base/Data-Monoid.html Any other improvements you'd make? Duncan _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Andrew Coppin
Andrew Coppin wrote:
>> I can't await the next Haskell standard, where at last all those >> extensions are builtin. > > This frightens me. > The example he had had the "uses" keyword, so I assume it's built in in the same way Perl pragma are built in. So you can happily ignore code when you see "uses" at the top of the file. ;) Although I could be wrong. Cheers, Cory _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Andrew Coppin
----- Original Message ---- From: Andrew Coppin <[hidden email]> > Which is why I personally prefer HiddenTypeVariables. (This has the advantage of using only pronouncible English >words, which means you can use it when speaking out loud.) Existential - English, easy to pronounce Quantify - English, easy to pronounce I know I've been seeing those backwards E's and upside down A's in not-so-advanced Maths courses for a long time (since high school, I'm sure) and I certainly encountered them before 'Boolean'. If you could do a geometry proof in high school, you have the Maths background need to understand the ideas. (How they apply to types is another story, but the words shouldn't be scary.) >> I can't await the next Haskell standard, where at last all those > extensions are builtin. > This frightens me. > At the moment, I understand how Haskell 98 works. There are lots of extensions > out there, but I don't have to care about that because I don't use them. If I read > somebody else's code and it contains a LANGUAGE pragma, I can immediately > tell that the code won't be comprehendable, so I don't need to waste time trying > to read it. But once Haskell' becomes standard, none of this holds any more. > Haskell' code will use obscure lanuage features without warning, and unless I > somehow learn every extension in the set, I'll never be able to read Haskell > again! (One presumes that they won't add any extensions which actually *break* > backwards compatibility, so hopefully I can still pretend these troublesome > extensions don't exist when writing my own code...) Some of the most useful libraries (e.g. parsec, generics) use these type system extensions (higher rank polymorphism, existentials). It would be great if these could be considered 'standard Haskell'. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Andrew Coppin
Andrew Coppin <[hidden email]> wrote:
> Ertugrul Soeylemez wrote: > > Andrew Coppin <[hidden email]> wrote: > > > >> I would suggest that ExistentiallyQuantifiedTypeVariables would be > >> an improvement [...] > > > > That must be a joke. Typing the long extension names in LANGUAGE > > pragmas over and over again is tiring and annoying enough already. > > We really don't need even longer names, and your "improvement" fills > > up almost half of the width of an 80 characters terminal. > > Which is why I personally prefer HiddenTypeVariables. (This has the > advantage of using only pronouncible English words, which means you > can use it when speaking out loud.) > > But, as I say, nobody is going to rename anything, so it's moot. Well, yes, unfortunately, unless someone proposes extension renamings together with a long paper about the psychological implications and advantages of using shorter names. > > I can't await the next Haskell standard, where at last all those > > extensions are builtin. > > This frightens me. > > At the moment, I understand how Haskell 98 works. There are lots of > extensions out there, but I don't have to care about that because I > don't use them. If I read somebody else's code and it contains a > LANGUAGE pragma, I can immediately tell that the code won't be > comprehendable, so I don't need to waste time trying to read it. But > once Haskell' becomes standard, none of this holds any more. Haskell' > code will use obscure lanuage features without warning, and unless I > somehow learn every extension in the set, I'll never be able to read > Haskell again! (One presumes that they won't add any extensions which > actually *break* backwards compatibility, so hopefully I can still > pretend these troublesome extensions don't exist when writing my own > code...) I think, the list of accepted extensions is well chosen. And don't worry, the extensions I'm talking about mainly, are easy to comprehend and very useful, for example multi-parameter type classes and rank-n types. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/ _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by Ross Paterson
On Sun, 18 Jan 2009, Ross Paterson wrote:
> Anyone can check out the darcs repos for the libraries, and post > suggested improvements to the documentation to [hidden email] > (though you have to subscribe). It doesn't even have to be a patch. > > Sure, it could be smoother, but there's hardly a flood of contributions. I noticed the Bool datatype isn't well documented. Since Bool is not a common English word, I figured it could use some haddock to help clarify it for newcomers. -- |The Bool datatype is named after George Boole (1815-1864). -- The Bool type is the coproduct of the terminal object with itself. -- As a coproduct, it comes with two maps i : 1 -> 1+1 and j : 1 -> 1+1 -- such that for any Y and maps u: 1 -> Y and v: 1 -> Y, there is a unique -- map (u+v): 1+1 -> Y such that (u+v) . i = u, and (u+v) . j = v -- as shown in the diagram below. -- -- 1 -- u --> Y -- ^ ^^ -- | / | -- i u + v v -- | / | -- 1+1 - j --> 1 -- -- In Haskell we call we define 'False' to be i(*) and 'True' to be j(*) -- where *:1. -- Furthermore, if Y is any type, and we are given a:Y and b:Y, then we -- can define u(*) = a and v(*) = b. -- From the above there is a unique map (u + v) : 1+1 -> Y, -- or in other words, (u+v) : Bool -> Y. -- Haskell has a built in syntax for this map: -- @if z then a else b@ equals (u+v)(z). -- -- From the commuting triangle in the diagram we see that -- (u+v)(i(*)) = u(*). -- Translated into Haskell notation, this law reads -- @if True then a else b = a@. -- Similarly from the other commuting triangle we see that -- (u+v)(j(*)) = v(*), which means -- @if False then a else b = b@ -- Russell O'Connor <http://r6.ca/> ``All talk about `theft,''' the general counsel of the American Graphophone Company wrote, ``is the merest claptrap, for there exists no property in ideas musical, literary or artistic, except as defined by statute.'' _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
[hidden email] wrote:
> On Sun, 18 Jan 2009, Ross Paterson wrote: > >> Anyone can check out the darcs repos for the libraries, and post >> suggested improvements to the documentation to [hidden email] >> (though you have to subscribe). It doesn't even have to be a patch. >> >> Sure, it could be smoother, but there's hardly a flood of contributions. > > I noticed the Bool datatype isn't well documented. Since Bool is not > a common English word, I figured it could use some haddock to help > clarify it for newcomers. > > -- |The Bool datatype is named after George Boole (1815-1864). > -- The Bool type is the coproduct of the terminal object with itself. > -- As a coproduct, it comes with two maps i : 1 -> 1+1 and j : 1 -> 1+1 > -- such that for any Y and maps u: 1 -> Y and v: 1 -> Y, there is a > unique -- map (u+v): 1+1 -> Y such that (u+v) . i = u, and (u+v) . j = v > -- as shown in the diagram below. > -- > -- 1 -- u --> Y > -- ^ ^^ > -- | / | > -- i u + v v > -- | / | > -- 1+1 - j --> 1 > -- > -- In Haskell we call we define 'False' to be i(*) and 'True' to be > j(*) -- where *:1. > -- Furthermore, if Y is any type, and we are given a:Y and b:Y, then > we -- can define u(*) = a and v(*) = b. > -- From the above there is a unique map (u + v) : 1+1 -> Y, > -- or in other words, (u+v) : Bool -> Y. > -- Haskell has a built in syntax for this map: > -- @if z then a else b@ equals (u+v)(z). > -- > -- From the commuting triangle in the diagram we see that > -- (u+v)(i(*)) = u(*). > -- Translated into Haskell notation, this law reads > -- @if True then a else b = a@. > -- Similarly from the other commuting triangle we see that > -- (u+v)(j(*)) = v(*), which means > -- @if False then a else b = b@ > part is I didn't actually find this difficult to read... Cory "lost touch with the real world" Knapp _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by roconnor
Am Sonntag, 18. Januar 2009 17:48 schrieb [hidden email]:
> On Sun, 18 Jan 2009, Ross Paterson wrote: > > Anyone can check out the darcs repos for the libraries, and post > > suggested improvements to the documentation to [hidden email] > > (though you have to subscribe). It doesn't even have to be a patch. > > > > Sure, it could be smoother, but there's hardly a flood of contributions. > > I noticed the Bool datatype isn't well documented. Since Bool is not a > common English word, I figured it could use some haddock to help clarify > it for newcomers. Thanks. Really helpful. A few minor typos, though. > > -- |The Bool datatype is named after George Boole (1815-1864). > -- The Bool type is the coproduct of the terminal object with itself. > -- As a coproduct, it comes with two maps i : 1 -> 1+1 and j : 1 -> 1+1 > -- such that for any Y and maps u: 1 -> Y and v: 1 -> Y, there is a unique > -- map (u+v): 1+1 -> Y such that (u+v) . i = u, and (u+v) . j = v > -- as shown in the diagram below. > -- > -- 1 -- u --> Y > -- ^ ^^ > -- | / | > -- i u + v v > -- | / | > -- 1+1 - j --> 1 You have the arrows i and j pointing in the wrong direction. > -- > -- In Haskell we call we define 'False' to be i(*) and 'True' to be j(*) Delete "we call". > -- where *:1. > -- Furthermore, if Y is any type, and we are given a:Y and b:Y, then we > -- can define u(*) = a and v(*) = b. > -- From the above there is a unique map (u + v) : 1+1 -> Y, > -- or in other words, (u+v) : Bool -> Y. > -- Haskell has a built in syntax for this map: > -- @if z then a else b@ equals (u+v)(z). > -- > -- From the commuting triangle in the diagram we see that > -- (u+v)(i(*)) = u(*). > -- Translated into Haskell notation, this law reads > -- @if True then a else b = a@. > -- Similarly from the other commuting triangle we see that > -- (u+v)(j(*)) = v(*), which means > -- @if False then a else b = b@ _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
2009/1/18 Daniel Fischer <[hidden email]>:
> Am Sonntag, 18. Januar 2009 17:48 schrieb [hidden email]: >> On Sun, 18 Jan 2009, Ross Paterson wrote: >> > Anyone can check out the darcs repos for the libraries, and post >> > suggested improvements to the documentation to [hidden email] >> > (though you have to subscribe). It doesn't even have to be a patch. >> > >> > Sure, it could be smoother, but there's hardly a flood of contributions. >> >> I noticed the Bool datatype isn't well documented. Since Bool is not a >> common English word, I figured it could use some haddock to help clarify >> it for newcomers. > > Thanks. Really helpful. A few minor typos, though. > >> >> -- |The Bool datatype is named after George Boole (1815-1864). >> -- The Bool type is the coproduct of the terminal object with itself. >> -- As a coproduct, it comes with two maps i : 1 -> 1+1 and j : 1 -> 1+1 >> -- such that for any Y and maps u: 1 -> Y and v: 1 -> Y, there is a unique >> -- map (u+v): 1+1 -> Y such that (u+v) . i = u, and (u+v) . j = v >> -- as shown in the diagram below. >> -- >> -- 1 -- u --> Y >> -- ^ ^^ >> -- | / | >> -- i u + v v >> -- | / | >> -- 1+1 - j --> 1 > > You have the arrows i and j pointing in the wrong direction. > >> -- >> -- In Haskell we call we define 'False' to be i(*) and 'True' to be j(*) > > Delete "we call". > >> -- where *:1. >> -- Furthermore, if Y is any type, and we are given a:Y and b:Y, then we >> -- can define u(*) = a and v(*) = b. >> -- From the above there is a unique map (u + v) : 1+1 -> Y, >> -- or in other words, (u+v) : Bool -> Y. >> -- Haskell has a built in syntax for this map: >> -- @if z then a else b@ equals (u+v)(z). >> -- >> -- From the commuting triangle in the diagram we see that >> -- (u+v)(i(*)) = u(*). >> -- Translated into Haskell notation, this law reads >> -- @if True then a else b = a@. >> -- Similarly from the other commuting triangle we see that >> -- (u+v)(j(*)) = v(*), which means >> -- @if False then a else b = b@ > > _______________________________________________ > Haskell-Cafe mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/haskell-cafe > Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
In reply to this post by roconnor
On Sun, Jan 18, 2009 at 5:48 PM, <[hidden email]> wrote:
> I noticed the Bool datatype isn't well documented. Since Bool is not a > common English word, I figured it could use some haddock to help clarify it > for newcomers. > > -- |The Bool datatype is named after George Boole (1815-1864). > -- The Bool type is the coproduct of the terminal object with itself. Russell, this does seem like it might be very helpful, but it might be useful to include a note about what category you are working in. People may sometimes naively assume that one is working in the category of Haskell/Hugs/GHC data types and Haskell functions, in which there are no terminal -- or initial -- objects ('undefined' and 'const undefined' are distinct maps between any two objects X and Y), or else in the similar category without lifted bottoms, in which the empty type is terminal and the unit type isn't ('undefined' and 'const ()' are both maps from any object X to the unit type). These niceties will not confuse the advanced reader, but it may help the beginner if you are more explicit. - Benja P.S. :-) _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
Free forum by Nabble | Edit this page |