Claus Reinke wrote:
the given example is too strict, the requirement is to generate the matched portion lazilly, and return the tail (unconsumed portion).

ah yes, without optimisations, Prelude.span builds up stack,

I don't quite understand why it does so at all.

  span p []       = ([],[])
  span p xs@(x:xs')
      | p x       = let (ys,zs) = span p xs' in (x:ys,zs)
      | otherwise = ([],xs)

I mean, the third line can return a tuple and the first element of the first list immediately. Where does the stack space come from?

True enough, the second component will be a tower

  snd (_, snd (_, snd (_, ...

but  snd  is tail recursive.

In principle the function should be capable of being written to run in constant space which the given example dose not.

Btw, even with the space leak prevention from the Sparud paper, it will be a linear chain of indirections. So, span doesn't run in constant space at all!

The problem is that when lazily deconstructing the first component, the second component has to be "deconstructed", too (reduced partially) or it will leak space. I mean, fetching the x from

 (x:ys, id zs)

should reduce the id , too. Of course, that should be up to the programmer's choice (partial reduction may be expensive), so is there a way to specify that in code?

Regards,
apfelmus

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

Reply via email to