
On Sat, Feb 06, 2010 at 01:45:58AM -0500, Brandon S. Allbery KF8NH wrote:
Andy Elvey wrote:
So, I may look at doing what I would call "lpred" and lsucc" - the predecessor and successor of a list element. I'm somewhat surprised that (from what I can tell) Haskell doesn't seem to have those two functions for a list. I may be wrong....
Again, lists don't work that way; a list in Haskell is a single immutable object, you can pull items from it using (!!), head, etc., but you can't have a pointer into the "middle" of a list. You can have a sublist (for example, `tail ["foo", "bar", "baz"]' = `["bar", "baz"]') --- but you can't get from there to the "foo", as it isn't part of that new list. (This despite the fact that what `tail' gives you is going to be shared in actual storage with the original list. You don't have a backpointer into that original list to follow.)
Although we can't have a pointer to the middle of a list [a], we can have another data struture that behaves sort of as if we had that pointer: a zipper. For example, http://hackage.haskell.org/packages/archive/ListZipper/1.1.1.0/doc/html/Data... To understand a list zipper you could think of it as something like struct zipper { list left, right; } So we track our "position" by tracking what's on the left and what's on the right. By using the API of the link above you could have something similar to what you wanted: lpred :: Zipper a -> a lpred = focus . left lsucc :: Zipper a -> a lsucc = focus . right -- Felipe.