-
-
Save treeowl/3e149df5a03c3ae2e51c51277919e189 to your computer and use it in GitHub Desktop.
zipRev :: [a] -> [b] -> [(a,b)] | |
zipRev xs ys = fr where | |
(fr, allbs) = go [] allbs xs ys | |
go acc ~(b':bs') (a:as) (b:bs) = ((a,b') : res, bss) | |
where | |
(res, bss) = go (b:acc) bs' as bs | |
go acc _ _ _ = ([], acc) |
as always, both ways are right! as long as the user knows which way they want, they can choose. :)
Wait, what do you mean by wrong end? Look at what each one produces...
I never tried, but AFAICS, foo [1..3] [1..4]
would produce two different results with your code and the one in the question. According to the high level rewrites in my first(?) comment.
yours would produce [(1,3),(2,2),(3,1)]
(up to swapping) but theirs -- [(4,1),(3,2),(2,3)]
. isn't it? or am I completely wrong there?
Looks like I was completely wrong there. My answer is wrong then, too. hmm. (edit: not!)
FWIW, I think you're right as a practical matter--laziness isn't a useful goal here.
wrong test case, huh! compare the results for zipRev [1..4] [10..12]
with your code and theirs -- I tested my re-write, at the top of my answer, with the added clause
.... g x c ([],t) = t
Yours produces [(1,12),(2,11),(3,10)]
but the augmented theirs -- [(2,12),(3,11),(4,10)]
.
Not wrong then. :)
It just aligns the lists at the wrong end:
1 2 3 4
12 11 10 -- OP's code
12 11 10 -- your code
About that, could you remind me, with the link to the SO entry? I remembered something vaguely about this, recently, but couldn't remember exactly what it was...
I don't know about the SO comment, but here's the GitHub issue. Remember: the function must be incremental/lazy the way liftA2
is, and must be time and space-optimal. You will almost certainly need to mash up ideas from the internal functions aptyMiddle
(which I created to implement (<*>)
and later liftA2
) and applicativeTree
(which was created, I believe by Wasserman, to implement replicateA
and thereby replicate
) to accomplish this mission.
thanks, will try to see what I can do.
The linked Haskell Wiki article claims to aim for laziness in "cancelling" the continuations, but the result doesn't strike me as very lazy. And I think they cut it off the wrong way (relative to
zipWith
) and I do it right!