Just clarifying the "pred" and "succ" functions in Haskell

Hi all - I'm doing a public-domain package of "functional" programs" in C, and that involves trying to replicate (in C) a number of Haskell functions. The two that I'm looking at now are "pred" and "succ". I've seen the examples on zvon.org, which give "pred 5" as being 4, and "pred B" as being "A". Ok, that's fine, no problem. However, is my understanding correct that this can be extended to lists (arrays in C) so that (for example) for a list ["foo", "bar", "baz"] , "pred "bar" " would give you "foo" , and "succ "bar" " would give you "baz"? Thanks in advance - bye for now - - Andy

On Feb 6, 2010, at 00:27 , Andy Elvey wrote:
However, is my understanding correct that this can be extended to lists (arrays in C) so that (for example) for a list ["foo", "bar", "baz"] , "pred "bar" " would give you "foo" , and "succ "bar" " would give you "baz"?
No. Leaving aside that you don't manipulate lists that way in Haskell, "bar" is a random value of type String (which is [Char]), not a member of an enumeration. For comparison:
data MyType = Foo | Bar | Baz deriving Enum; -- pred Bar = Foo, succ Bar = Baz
Some languages (e.g. Perl) do give an enumerable value to Strings, but `succ "Bar"' would be something like "Baq". (This could be done in Haskell, with some pain; it starts with `instance (Enum a, Bounded a) => Enum [a] where...'.) You can't go from a string like "Bar" to whatever lists might contain that string (and what if multiple lists contained it?), so there's no way to get an interpretation like that; you would need an enumerator which had access both to the list and the member in question, whereas Enum has access only to the type. (There exist dependent type systems where you could encode that information into a defined (sub)type, but Haskell doesn't support it directly.) What you *can* do is that, because the types of list and array indexes are members of Enum, you can for example use Data.List.index to determine the index (if any!) of that item in your list, then take prev or succ of that. Beware of running off the end of the list, though. (It's also more complicated for arrays because array indexes are themselves defined by a typeclass `Ix'.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Feb 6, 2010, at 00:27 , Andy Elvey wrote:
However, is my understanding correct that this can be extended to lists (arrays in C) so that (for example) for a list ["foo", "bar", "baz"] , "pred "bar" " would give you "foo" , and "succ "bar" " would give you "baz"?
No. Leaving aside that you don't manipulate lists that way in Haskell, "bar" is a random value of type String (which is [Char]), not a member of an enumeration. For comparison:
data MyType = Foo | Bar | Baz deriving Enum; -- pred Bar = Foo, succ Bar = Baz
Some languages (e.g. Perl) do give an enumerable value to Strings, but `succ "Bar"' would be something like "Baq". (This could be done in Haskell, with some pain; it starts with `instance (Enum a, Bounded a) => Enum [a] where...'.) You can't go from a string like "Bar" to whatever lists might contain that string (and what if multiple lists contained it?), so there's no way to get an interpretation like that; you would need an enumerator which had access both to the list and the member in question, whereas Enum has access only to the type. (There exist dependent type systems where you could encode that information into a defined (sub)type, but Haskell doesn't support it directly.)
What you *can* do is that, because the types of list and array indexes are members of Enum, you can for example use Data.List.index to determine the index (if any!) of that item in your list, then take prev or succ of that. Beware of running off the end of the list, though. (It's also more complicated for arrays because array indexes are themselves defined by a typeclass `Ix'.) Hi Brandon - thanks very much for that! Ok. Yes, that is exactly what I was after. I was indeed thinking that "pred" and "succ" related to the "previous" and "next" elements in a
Brandon S. Allbery KF8NH wrote: list, but I now see that that is not the case. 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.... Anyway - thanks again. Bye for now - - Andy
participants (2)
-
Andy Elvey
-
Brandon S. Allbery KF8NH