Comments from OCaml Hacker Brian Hurt

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
237 messages Options
1 ... 789101112
Reply | Threaded
Open this post in threaded view
|

Re: Comments from OCaml Hacker Brian Hurt

David Virebayre
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
Reply | Threaded
Open this post in threaded view
|

Re: Comments from OCaml Hacker Brian Hurt

greenrd
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
Reply | Threaded
Open this post in threaded view
|

Re: Functors [Comments from OCaml Hacker Brian Hurt]

Heinrich Apfelmus
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
Reply | Threaded
Open this post in threaded view
|

Re: Re: Comments from OCaml Hacker Brian Hurt

wren ng thornton
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
Reply | Threaded
Open this post in threaded view
|

Re: Comments from OCaml Hacker Brian Hurt

Heinrich Apfelmus
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
Reply | Threaded
Open this post in threaded view
|

Re: Re: Functors [Comments from OCaml Hacker Brian Hurt]

Andrew Coppin
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
Reply | Threaded
Open this post in threaded view
|

Re: Functors [Comments from OCaml Hacker Brian Hurt]

Heinrich Apfelmus
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
Reply | Threaded
Open this post in threaded view
|

Re: Re: Comments from OCaml Hacker Brian Hurt

Andrew Coppin
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
Reply | Threaded
Open this post in threaded view
|

Re: Functors [Comments from OCaml Hacker Brian Hurt]

Andrew Coppin
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
Reply | Threaded
Open this post in threaded view
|

Re: Functors [Comments from OCaml Hacker Brian Hurt]

Ryan Ingram
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
Reply | Threaded
Open this post in threaded view
|

Re: Comments from OCaml Hacker Brian Hurt

Ross Paterson
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
Reply | Threaded
Open this post in threaded view
|

Re: Re[2]: Comments from OCaml Hacker Brian Hurt

Duncan Coutts
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
Reply | Threaded
Open this post in threaded view
|

Re: Re: Comments from OCaml Hacker Brian Hurt

Cory Knapp
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
Reply | Threaded
Open this post in threaded view
|

Re: Re: Comments from OCaml Hacker Brian Hurt

Robert Greayer
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
Reply | Threaded
Open this post in threaded view
|

Re: Comments from OCaml Hacker Brian Hurt

Ertugrul Söylemez
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
Reply | Threaded
Open this post in threaded view
|

Improved documentation for Bool (Was: Comments from OCaml Hacker Brian Hurt)

roconnor
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
Reply | Threaded
Open this post in threaded view
|

Re: Improved documentation for Bool (Was: Comments from OCaml Hacker Brian Hurt)

Cory Knapp
[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@
>
I'm going to go ahead and assume this was a joke and crack up... The sad
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
Reply | Threaded
Open this post in threaded view
|

Re: Improved documentation for Bool (Was: Comments from OCaml Hacker Brian Hurt)

Daniel Fischer-4
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
Reply | Threaded
Open this post in threaded view
|

Re: Improved documentation for Bool (Was: Comments from OCaml Hacker Brian Hurt)

Eugene Kirpichov
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).
Also, "equals (a+b)(z)" should be here.

>> --
>> -- 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
Reply | Threaded
Open this post in threaded view
|

Re: Improved documentation for Bool (Was: Comments from OCaml Hacker Brian Hurt)

Benja Fallenstein
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
1 ... 789101112