Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 106, Issue 38

2012-06-26 Thread John Lato
 Message: 12
 Date: Wed, 27 Jun 2012 00:19:30 +0200
 From: Tillmann Rendel ren...@informatik.uni-marburg.de
 Subject: Re: [Haskell-cafe] Martin Odersky on What's wrong with
        Monads
 Cc: haskell-cafe@haskell.org
 Message-ID: 4fea3572.5060...@informatik.uni-marburg.de
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed

 Hi,

 MightyByte wrote:
 Of course every line of your program that uses a Foo will change if you 
 switch
 to IO Foo instead.

 But we often have to also change lines that don't use Foo at all. For
 example, here is the type of binary trees of integers:

   data Tree = Leaf Integer | Branch (Tree Integer) (Tree Integer)

 A function to add up all integers in a tree:

   amount:: Tree - Integer
   amount (Leaf x) = x
   amount (Branch t1 t2) = amountt1 + amountt2

 All fine so far. Now, consider the following additional requirement: If
 the command-line flag --multiply is set, the function amount computes
 the product instead of the sum.

 In a language with implicit side effects, it is easy to implement this.
 We just change the third line of the amount function to check whether to
 call (+) or (*). In particular, we would not touch the other two lines.

 How would you implement this requirement in Haskell without changing the
 line amount (Leaf x) = x?

Why would you do that even in an imperative language?  The program
logic turns into a spaghetti mess, and it's much harder to test.

I would write Tree like this:

data Tree a = Leaf a | Branch (Tree a) ( Tree a)
  deriving (Foldable, Show)

and instead of an amount function I would use a fold.  If you like,
you can use ala from Control.Newtype

*Main Data.Foldable Data.Monoid let t1 = Branch (Leaf 1) (Branch
(Leaf 4) (Leaf 5)) :: Tree Int
*Main Data.Foldable Data.Monoid ala Sum foldMap t1
10
*Main Data.Foldable Data.Monoid ala Product foldMap t1
20

Now the amount calculation can be something like

amount :: Num a = Tree a - IO a
amount tree = multFlag = \b - if b then ala Product foldMap tree
else ala Sum foldMap tree


although I probably wouldn't actually write it unless it was called in
more than one place.  There are other ways to write it too; the
important part is that checking the configuration is completely
separate from the tree traversal.

Plus, if it changes again (now there's another flag that says to
ignore values == n or something, you can use the same fold, just
change the function that's passed to it (or the monoid instance if
you're using that).

Plus, this type of code is much simpler to debug, test, and maintain
than imperative-style magic functions.

Cheers,
John

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 106, Issue 38

2012-06-26 Thread Richard O'Keefe

On 27/06/2012, at 12:51 PM, John Lato wrote:
 
 data Tree a = Leaf a | Branch (Tree a) ( Tree a)
  deriving (Foldable, Show)

While I am familiar with deriving (Show),
I am not familiar with deriving (Foldable),
which looks rather useful.

http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/deriving.html
just says With -XDeriveFoldable, you can derive instances of the
class Foldable, defined in Data.Foldable. but it provides no details.

Would you care to explain more about deriving (Foldable)?


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 106, Issue 38

2012-06-26 Thread John Lato
On Wed, Jun 27, 2012 at 9:15 AM, Richard O'Keefe o...@cs.otago.ac.nz wrote:

 On 27/06/2012, at 12:51 PM, John Lato wrote:

 data Tree a = Leaf a | Branch (Tree a) ( Tree a)
  deriving (Foldable, Show)

 While I am familiar with deriving (Show),
 I am not familiar with deriving (Foldable),
 which looks rather useful.

 http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/deriving.html
 just says With -XDeriveFoldable, you can derive instances of the
 class Foldable, defined in Data.Foldable. but it provides no details.

 Would you care to explain more about deriving (Foldable)?

There's not much to explain, DeriveFoldable basically does just that;
automatically provide an instance of the Foldable class for a data
type.  I think the original proposal for DeriveFoldable was from Twan
van Laarhoven, 
http://www.mail-archive.com/haskell-prime@haskell.org/msg02116.html,
and there's a little bit of history on GHC's trac,
http://hackage.haskell.org/trac/ghc/ticket/2953.  The current
implementation probably hasn't changed much since Simon PJ's original
patch, although there's probably substantial overlap with ghc's
generics these days.

As for the Foldable class itself, the docs at
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Foldable.html
are pretty good.  It lets you perform a number of folds (left, right,
monoidal) over arbitrary datatypes, not just lists.

I think that's about it.  Although I'm not the best person to explain
either the DeriveFoldable algorithm or the different uses of folds;
maybe someone else would be able to fill in anything I've missed.

John L.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 106, Issue 38

2012-06-26 Thread Richard O'Keefe

On 27/06/2012, at 3:18 PM, John Lato wrote:

 On Wed, Jun 27, 2012 at 9:15 AM, Richard O'Keefe o...@cs.otago.ac.nz wrote:
 
 On 27/06/2012, at 12:51 PM, John Lato wrote:
 
 data Tree a = Leaf a | Branch (Tree a) ( Tree a)
  deriving (Foldable, Show)
 
 While I am familiar with deriving (Show),
 I am not familiar with deriving (Foldable),
 which looks rather useful.
 
 http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/deriving.html
 just says With -XDeriveFoldable, you can derive instances of the
 class Foldable, defined in Data.Foldable. but it provides no details.
 
 Would you care to explain more about deriving (Foldable)?
 
 There's not much to explain, DeriveFoldable basically does just that;
 automatically provide an instance of the Foldable class for a data
 type.

That was sufficiently obvious, yes.
The question remains, ***WHAT*** instance?

  I think the original proposal for DeriveFoldable was from Twan
 van Laarhoven, 
 http://www.mail-archive.com/haskell-prime@haskell.org/msg02116.html,

which goes into a great deal of detail about what deriving (Functor)
does, but none whatsoever about what deriving (Foldable) does.  Even
for Functor, another 3 or 4 nontrivial examples would be nice.

 and there's a little bit of history on GHC's trac,
 http://hackage.haskell.org/trac/ghc/ticket/2953.  The current
 implementation probably hasn't changed much since Simon PJ's original
 patch, although there's probably substantial overlap with ghc's
 generics these days.

That trac entry contains one sentence that seems to still apply:

  What is missing is a section in the user manual describing the changes.

It refers to section 8.5, which is now 7.5, and there is still no
adequate documentation there.
 
 As for the Foldable class itself, the docs at
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Foldable.html
 are pretty good. 

Yes, Foldable *is* documented.
However, that page says nothing whatever about deriving (Foldable).




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe