Re: [Haskell-cafe] and from standard Prelude

2010-08-24 Thread Jan-Willem Maessen
On Wed, Aug 18, 2010 at 9:56 PM, wren ng thornton w...@freegeek.org wrote:
 Oleg Lobachev wrote:

 #ifdef USE_REPORT_PRELUDE
 and                     =  foldr () True
 or                      =  foldr (||) False
 #else
 and []          =  True
 and (x:xs)      =  x  and xs
 or []           =  False
 or (x:xs)       =  x || or xs

 {-# RULES

 and/build     forall (g::forall b.(Bool-b-b)-b-b) .
                and (build g) = g () True

 or/build      forall (g::forall b.(Bool-b-b)-b-b) .
               or (build g) = g (||) False

 #-}
 #endif

 The thing I find puzzling is that the foldr is inlined. The (regular) clever
 optimizations for build/foldr seem like they should already handle this
 without the need for the extra rules. I wonder how much is gained by
 specializing to ()/True instead of relying on the regular deforestation?

The above code does not inline and / or, *unless they are fused using
the RULES.*  There's not really any benefit to inlining them
otherwise, and it duplicates code.

-Jan-Willem Maessen


 --
 Live well,
 ~wren
 ___
 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] and from standard Prelude

2010-08-24 Thread wren ng thornton

On 8/24/10 1:55 PM, Jan-Willem Maessen wrote:

On Wed, Aug 18, 2010 at 9:56 PM, wren ng thorntonw...@freegeek.org  wrote:

The thing I find puzzling is that the foldr is inlined. The (regular) clever
optimizations for build/foldr seem like they should already handle this
without the need for the extra rules. I wonder how much is gained by
specializing to ()/True instead of relying on the regular deforestation?


The above code does not inline and / or, *unless they are fused using
the RULES.*  There's not really any benefit to inlining them
otherwise, and it duplicates code.


Ah, that makes sense. Thanks.

--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] and from standard Prelude

2010-08-18 Thread Oleg Lobachev
Hello all,

the and function, and :: [Bool] - Bool is defined in two different ways in the 
latest Prelude.

I would expect it to be

 and = foldr () True

However, there is a further recursive definition, and it is the one used! See 
http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/src/GHC-List.html#and

 #ifdef USE_REPORT_PRELUDE
 and =  foldr () True
 or  =  foldr (||) False
 #else
 and []  =  True
 and (x:xs)  =  x  and xs
 or []   =  False
 or (x:xs)   =  x || or xs
 
 {-# RULES
 
 and/build forall (g::forall b.(Bool-b-b)-b-b) . 
 
 and (build g) = g () True

 or/build  forall (g::forall b.(Bool-b-b)-b-b) . 
 
or (build g) = g (||) False
 
 #-}
 #endif

Is there any reason for that besides some clever optimizations? I am 
particularly interested in the behavior of and for infinite lists and these two 
versions are equivalent in this aspect.

Greetings,
Oleg



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


Re: [Haskell-cafe] and from standard Prelude

2010-08-18 Thread Ivan Lazar Miljenovic
Oleg Lobachev lobac...@mathematik.uni-marburg.de writes:

 #else
 and []  =  True
 and (x:xs)  =  x  and xs
 or []   =  False
 or (x:xs)   =  x || or xs
 
 {-# RULES
 
 and/build forall (g::forall b.(Bool-b-b)-b-b) . 
 
 and (build g) = g () True

 or/build  forall (g::forall b.(Bool-b-b)-b-b) . 
 
or (build g) = g (||) False
 
 #-}
 #endif

 Is there any reason for that besides some clever optimizations? I am
 particularly interested in the behavior of and for infinite lists and
 these two versions are equivalent in this aspect.

Precisely for clever optimisations.  See the paper A Short Cut to
Deforestation by Andrew Gill, John Launchbury and Simon Peyton Jones
(from 1993 apparently; I'm going off a copy I have locally).

-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
IvanMiljenovic.wordpress.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] and from standard Prelude

2010-08-18 Thread Duncan Coutts
On 18 August 2010 10:05, Oleg Lobachev
lobac...@mathematik.uni-marburg.de wrote:
 Hello all,

 the and function, and :: [Bool] - Bool is defined in two different ways in 
 the latest Prelude.

 I would expect it to be

 and = foldr () True

 However, there is a further recursive definition, and it is the one used!

This is just an issue of specification vs implementation. The spec
from the H98 report is

and = foldr () True

An H98 implementation must provide an implementation of 'and' that is
equal to this specification. So the above can be used as the
implementation, or a directly recursive implementation or versions
using build/fold or unfold/destroy fusion, or any other implementation
would also be ok so long as they are equal to the spec. As Ivan says,
GHC's implementation of 'and' uses build/fold fusion.

Note that 'equal' includes all partial and total lists, so you can
rely on the above spec to reason about the behaviour on infinite lists
and expect that reasoning to work for correct H98 implementations.
That said, there are a couple functions where the obviously sensible,
and standard implementations differ from the H98 spec for some partial
values. Notably splitAt is specified badly in the H98 report (it is
too lazy).

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


Re: [Haskell-cafe] and from standard Prelude

2010-08-18 Thread Oleg Lobachev
Hello,

On Aug 18, 2010, at 13:44 , Duncan Coutts wrote:
 This is just an issue of specification vs implementation. The spec
 from the H98 report is
 
 and = foldr () True
[snip]
 Note that 'equal' includes all partial and total lists, so you can
 rely on the above spec to reason about the behaviour on infinite lists
 and expect that reasoning to work for correct H98 implementations.

ok, thank you.

It was precisely the reason for my question. I used the fold-based definition 
in my ramblings and then bothered to look into the Prelude code. ;)

 That said, there are a couple functions where the obviously sensible,
 and standard implementations differ from the H98 spec for some partial
 values. Notably splitAt is specified badly in the H98 report (it is
 too lazy).

By the way, does some good reading on streams in Haskell exist? I am interested 
primarily in a theoretical foundation, which should however be somehow related 
to Haskell. My guess would be the relation of streams, represented as lazy, not 
completely evaluated lists, and the evaluation strategies. The practical part 
is easier, feeding [1..] to various functions in GHCi. I have found 
[Ennals2003optimistic], but it seems to go in wrong direction.

[Ennals2003optimistic]: Robert Ennals, Simon Peyton Jones. Optimistic 
evaluation: an adaptive evaluation strategy for non-strict programs. ICFP 
2003. http://portal.acm.org/citation.cfm?id=944705.944731

Greetings,
Oleg



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


Re: [Haskell-cafe] and from standard Prelude

2010-08-18 Thread Duncan Coutts
On 18 August 2010 13:29, Oleg Lobachev
lobac...@mathematik.uni-marburg.de wrote:

 By the way, does some good reading on streams in Haskell exist? I am 
 interested primarily in a theoretical foundation, which should however be 
 somehow related to Haskell. My guess would be the relation of streams, 
 represented as lazy, not completely evaluated lists, and the evaluation 
 strategies. The practical part is easier, feeding [1..] to various functions 
 in GHCi. I have found [Ennals2003optimistic], but it seems to go in wrong 
 direction.

If you mean streams as in stream fusion then I hope chapter 3 of my
PhD thesis will be of some help (when it is finally published). If you
mean streams as in always-infinite co-inductive sequences then a good
starting point is probably Functional Pearl: Streams and Unique Fixed
Points by Ralf Hinze.

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


Re: [Haskell-cafe] and from standard Prelude

2010-08-18 Thread wren ng thornton

Oleg Lobachev wrote:

#ifdef USE_REPORT_PRELUDE
and =  foldr () True
or  =  foldr (||) False
#else
and []  =  True
and (x:xs)  =  x  and xs
or []   =  False
or (x:xs)   =  x || or xs

{-# RULES

and/build forall (g::forall b.(Bool-b-b)-b-b) . 


and (build g) = g () True

or/build  forall (g::forall b.(Bool-b-b)-b-b) . 


   or (build g) = g (||) False

#-}
#endif


Is there any reason for that besides some clever optimizations?



The thing I find puzzling is that the foldr is inlined. The (regular) 
clever optimizations for build/foldr seem like they should already 
handle this without the need for the extra rules. I wonder how much is 
gained by specializing to ()/True instead of relying on the regular 
deforestation?


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe