public
Last active — forked from depp/Enum.hs

Demonstration of how incorrect (Enum x, Enum y) => Enum (x, y) instance can be used for Enum a => Enum (a,a)

  • Download Gist
Enum.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
{-# LANGUAGE FlexibleInstances #-}
 
-- See http://stackoverflow.com/questions/9967790/instance-in-haskell
 
instance (Enum a) => Enum (a, a) where
fromEnum (x,y) =
k^2 + 2*j + if permuted then 1 else 0
where
k = max (fromEnum x) (fromEnum y)
j = min (fromEnum x) (fromEnum y)
permuted = (fromEnum y) > (fromEnum x)
toEnum n =
let k = floor . sqrt $ fromIntegral n
(j, permdAdd) = (n-k^2) `divMod` 2
permute (x,y) | permdAdd>0 = (toEnum y, toEnum x)
| otherwise = (toEnum x, toEnum y)
in permute (k, j)
 
data A = A1 | A2 deriving (Show, Enum)
data B = B1 | B2 | B3 deriving (Show, Enum)
 
main = do
print [(A1,A1)..(A2,A2)]
print [(B1,B1)..(B3,B3)]
 
 
-- $ runhaskell tupleenum.hs
-- [(A1,A1),(A2,A1),(A1,A2),(A2,A2)]
-- [(B1,B1),(B2,B1),(B1,B2),(B2,B2),(B3,B1),(B1,B3),(B3,B2),(B2,B3),(B3,B3)]

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.