Consider I was designing a Monopoly game:
data Board = GO | A1 | CC1 | A2 | T1 | R1 | B1 | CH1 | B2 | B3 |
JAIL | C1 | U1 | C2 | C3 | R2 | D1 | CC2 | D2 |
There is a disgusting way to define an efficient wrapping Enum
instance without doing much by hand.
{-# LANGUAGE MagicHash #-}
import GHC.Exts (Int (..), tagToEnum#, dataToTag# )
-- dataToTag# :: a -> Int#
-- tagToEnum# :: Int# -> a
Now you can write
data Board = ... deriving (Eq, Ord, Bounded)
instance Enum Board where
fromEnum a = I# (dataToTag# a)
toEnum x | x < 0 || x > fromEnum (maxBound :: Board) =
error "Out of range"
toEnum (I# t) = tagToEnum# t
succ x | x == maxBound = minBound
| otherwise == toEnum (fromEnum x + 1)
pred x ....