[Haskell-cafe] Basic list exercise

David Feuer david.feuer at gmail.com
Sun Mar 26 19:53:00 UTC 2023


I don't know prolog, but I believe the answer to your last question is no.
The functions will actually be function closures in this case. There's no
way to leave a (native) Haskell list open to being extended at the end,
except to the extent that lazy evaluation does so. Somewhat separately,
while it would be possible for a Haskell implementation to construct
strict-spined list-like structures with constant stack space using tail
recursion modulo cons, GHC doesn't do that.

On Sun, Mar 26, 2023, 1:59 PM Todd Wilson <twilson at csufresno.edu> wrote:

> I want to thank all of those who contributed to this thread. If I can
> summarize the contributions (feel free to clarify any misrepresentations):
>
>    - The code I provided for this problem is probably optimal, except
>    perhaps for the small point about using an @-pattern in `run` to avoid
>    reconstructing `y:ys` in the last line -- but isn't this also something the
>    compiler could easily discover and take advantage of without explicit
>    direction?
>    - The compiler will avoid breaking down and reconstructing pairs on
>    each recursive call, even though that is how it is coded.
>    - Although nobody commented on my Prolog version (perhaps because this
>    is a Haskell list!), the point I made there about compiling this as a tail
>    call that doesn't grow the stack should also apply to Haskell (does it?).
>    One thing that's clear from the Prolog code is that it goes down the input
>    list and distributes the elements to one of two places -- the end of the
>    current run or the beginning of a new run -- interspersed with some
>    cons-cell creation. Is that what's happening in Haskell also?
>    - Reference was made to Haskell's `sort` implementation, which
>    essentially finds runs (increasing and decreasing) in the input before
>    repeatedly merging them in pairs until one run remains. Decreasing runs can
>    be turned into increasing ones by using a tail call with a list
>    accumulator, the way iterative reverse works. But increasing runs are
>    handled in the same way that my Prolog code does, essentially by using what
>    appears to be the Haskell equivalent of Prolog's difference-lists:
>    functions whose arguments are the extendible ends of lists.
>
> I'm intrigued by the idea mentioned in this last bullet point. Is this
> functional equivalent of Prolog's difference lists -- essentially partial
> data structures that are grown top-down rather than bottom-up, actually
> efficient? Is there an overhead penalty to be paid for using functions
> here, or is it compiled away into Prolog-like tail calls that fill in the
> missing parts of the data structure?
>
> Todd Wilson
>
> On Thu, Mar 16, 2023 at 6:33 PM Todd Wilson <twilson at csufresno.edu> wrote:
>
>> Dear Cafe,
>>
>> Here's a basic exercise in list processing: define a function
>>
>> runs :: Ord a => [a] -> [[a]]
>>
>> that breaks up its input list into a list of increasing "runs"; e.g.,
>>
>> runs [3,4,5,6,2,3,4,1,2,1]  --->  [[3,4,5,6],[2,3,4],[1,2],[1]]
>>
>> A natural solution is the following:
>>
>> runs [] = []
>> runs (x:xs) = let (ys, zs) = run x xs
>>               in (x:ys) : runs zs
>>   where
>>     run x [] = ([], [])
>>     run x (y:ys) = if x <= y
>>                    then let (us, vs) = run y ys
>>                         in (y:us, vs)
>>                    else ([], y:ys)
>>
>> My question: can we do better than this? It seems that this solution is
>> constantly building and breaking apart pairs. (Or is it, when optimized?)
>>
>> Todd Wilson
>>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20230326/fb540e3b/attachment.html>


More information about the Haskell-Cafe mailing list