# safe versions of pred and succ?

3 messages
Open this post in threaded view
|
Report Content as Inappropriate

## safe versions of pred and succ?

 Suppose I have a function f :: (Enum a) => a -> ... f x ... = ...pred x ... If a is also an instance of Bounded, then I get a runtime error if pred minBound is evaluated during evaluation of f. If I try to protect the use of pred x with a check using minBound, then I have to add a Bounded constraint on type a, which would mean, for example, that I can no longer use f with type Integer. Do I need two different versions of f, one for Bounded a and one for non-Bounded a? Is there a more elegant way to take care of this problem? I don't know much about all of the type magic available in GHC. For example, from another list message, groupConsecutive :: (Enum a,Eq a) => [a] -> [[a]] groupConsecutive = foldr go []      where go x ls@(hd@(y:_):yss)              | x == y || x == pred y = (x:hd):yss              | otherwise             = [x]:ls            go x [] = [[x]]  > groupConsecutive [1,2,3,7,8,10,11,12] [[1,2,3],[7,8],[10,11,12]]  > groupConsecutive ([1,0,1,2]::[Word]) *** Exception: Enum.pred{Word}: tried to take `pred' of minBound In the first go case, if type a is also Bounded, y == minBound and x /= y, then we know already that x /= pred y, we want the guard to fail and that we pass to the otherwise guard to start a new sublist. But how to implement it without making the function unavailable for un-Bounded types? Graham _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|
Report Content as Inappropriate

## Re: safe versions of pred and succ?

 On 01/14/2017 02:35 AM, Graham Gill wrote: > > Do I need two different versions of f, one for Bounded a and one for > non-Bounded a? Is there a more elegant way to take care of this problem? > I don't know much about all of the type magic available in GHC. > You probably want your own typeclass instead of Enum, even if it means generating a bunch of very boring instances of it for the types you want "f" to work on. The fact that "pred" should throw a runtime error on "minBound" is a documented fact of the Enum typeclass, and you should stay far far away from such things in your own code. Besides that, there's a weird interaction between the semantic meaning of Enum and Bounded. For example, here's a perfectly valid enumeration of boolean values:   True, False, True, False, ... In your case it would be fine to have (pred False) == True, but instead you get a runtime error thanks to the Bounded instance. So being Bounded rules out some otherwise valid (and fine for your purposes) Enum instances. Your "f" should also work on a singleton type:   ghci> data Foo = Foo deriving (Eq,Show)   ghci> instance Enum Foo where toEnum _ = Foo; fromEnum _ = 0;   ghci> groupConsecutive [Foo,Foo,Foo,Foo]   [[Foo,Foo,Foo,Foo]] But any Bounded instance for Foo would mess that up. Basically, the pre-existing Enum instances aren't exactly what you want. _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners