runs([], []).
runs([X|Xs], [[X|Ys]|Rs]) :-
run(X, Xs, Ys, Zs),
runs(Zs, Rs).
run(_, [], [], []) :- !.
run(X, [Y|Ys], [Y|Us], Vs) :- X =< Y, !, run(Y, Ys, Us, Vs).
run(_, Ys, [], Ys).
If you use a case statement instead of a let statement in the recursive case, then GHC will know the pairs are being made and immediately taken apart, and will optimize it to use unboxed pairs internally.On Thu, Mar 16, 2023, 20:33 Todd Wilson <twilson@csufresno.edu> wrote:_______________________________________________Dear Cafe,Here's a basic exercise in list processing: define a functionthat breaks up its input list into a list of increasing "runs"; e.g.,runs :: Ord a => [a] -> [[a]]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: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?)runs [] = []
runs (x:xs) = let (ys, zs) = run x xsin (x:ys) : runs zswhere
run x [] = ([], [])
run x (y:ys) = if x <= ythen let (us, vs) = run y ysin (y:us, vs)else ([], y:ys)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.