[Haskell-cafe] V.I.P.s and the associativity of merge'
Will Ness
will_n48 at yahoo.com
Sat Jan 1 12:29:15 CET 2011
Heinrich Apfelmus <apfelmus <at> quantentunnel.de> writes:
>
> Will Ness wrote:
> > Heinrich Apfelmus writes:
> >> Here an example where the VIP merge would give a different result
> >>
> >> bad = tfold $ (1:10:undefined) : (2:3:5:undefined) : (4:undefined) :
> >> error "bad"
> >
> > The reason to *not* have the "lazy" patterns in foldTree for primes, as
Daniel
> > Fischer discovered back then, is that they give it a space leak. Case in
point -
> > http://ideone.com/DLHp2 :
> >
> > [...]
> >
> > tfold ((x:xs):t) = x : xs `merge` tfold (pairs t)
> > where pairs ((x:xs):ys:t) = (x : merge xs ys) : pairs t
> >
> > hfold xs = serve . foldTree mergeP . map vip $ xs
> > hfold' xs = serve . foldTree' mergeP . map vip $ xs
> >
> > foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)
> > where pairs ~(x: ~(y:ys)) = f x y : pairs ys
> >
> > foldTree' f (x:xs) = x `f` foldTree' f (pairs xs)
> > where pairs (x: (y:ys)) = f x y : pairs ys
> >
> > [...]
> >
> > so hfold' too appears to be over-eager to-the-right, although still more
> > productive than tfold.
>
> Ah, the lazy patterns in foldTree are a different issue, sorry for my
> bad choice of example.
>
> While I still don't understand the trade-off that turns the lazy
> patterns into a space leak, there is no harm in allowing foldTree to
> see the complete spine of the list. What we do want to forbid is looking
> at the elements of that list too early.
This turns out to be too optimistic a demand on data, in general.
> In other words, the example
> should read
>
> bad = tfold $
> (1:10:undefined) : (2:3:5:undefined) : (4:undefined)
> : repeat (error "bad" : undefined)
>
> i.e. the previously unknown tail is replaced with an infinite list of
> undefined elements. This example can properly distinguish between the
> not-so-correct tfold and proper VIP implementations (or other
> implementations that don't do unnecessary comparisons).
>
will have to think this over, but in the mean time, they *both* turn out to be
*completely* and utterly *wrong* :) in a general case (although probably for
different reasons).
Here's where:
*Main> mapM_ print $ take 5 $ map (take 10)
[concatMap (replicate 3) [n,n+1..]|n<-[1..]]
[1,1,1,2,2,2,3,3,3,4]
[2,2,2,3,3,3,4,4,4,5]
[3,3,3,4,4,4,5,5,5,6]
[4,4,4,5,5,5,6,6,6,7]
[5,5,5,6,6,6,7,7,7,8]
*Main> take 20 $ hfold [concatMap (replicate 3) [n,n+1..]|n<-[1..]]
[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7]
*Main> take 20 $ tfold [concatMap (replicate 3) [n,n+1..]|n<-[1..]]
[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7]
when it should'a been
[1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4]
Cheers,
:)
> Regards,
> Heinrich Apfelmus
>
> --
> http://apfelmus.nfshost.com
>
More information about the Haskell-Cafe
mailing list