module Data.Enum_Class(Enum(..)) where import qualified Prelude() import Primitives import Control.Error import Data.Bool import Data.Function((.)) import Data.List_Type import {-# SOURCE #-} Data.Typeable class Enum a where succ :: a -> a pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int enumFrom :: a -> [a] enumFromThen :: a -> a -> [a] enumFromTo :: a -> a -> [a] enumFromThenTo :: a -> a -> a -> [a] succ = toEnum . primIntAdd 1 . fromEnum pred = toEnum . primIntSubR 1 . fromEnum enumFrom x = [ toEnum i | i <- [fromEnum x ..] ] enumFromThen x y = [ toEnum i | i <- [fromEnum x, fromEnum y ..] ] enumFromTo x y = [ toEnum i | i <- [fromEnum x .. fromEnum y] ] enumFromThenTo x1 x2 y = [ toEnum i | i <- [fromEnum x1, fromEnum x2 .. fromEnum y] ] eftInt :: Int -> Int -> [Int] eftInt x y = if x `primIntGT` y then [] else go x where go n = n : if n `primIntEQ` y then [] else go (n `primIntAdd` 1) efttIntUp :: Int -> Int -> Int -> [Int] -- x2 >= x1 efttIntUp x1 x2 y | y `primIntLT` x2 = if y `primIntLT` x1 then [] else [x1] | otherwise = let delta = x2 `primIntSub` x1 y' = y `primIntSub` delta go x = if x `primIntGT` y' then [x] else x : go (x `primIntAdd` delta) in x1 : go x2 efttIntDown :: Int -> Int -> Int -> [Int] -- x2 <= x1 efttIntDown x1 x2 y | y `primIntGT` x2 = if y `primIntGT` x1 then [] else [x1] | otherwise = let delta = x2 `primIntSub` x1 y' = y `primIntSub` delta go x = if x `primIntLT` y' then [x] else x : go (x `primIntAdd` delta) in x1 : go x2 -- This instance is difficult to put in Data.Int, -- so it gets to live here. instance Enum Int where succ x = if x `primIntEQ` maxInt then error "Int.succ: overflow" else x `primIntAdd` 1 pred x = if x `primIntEQ` minInt then error "Int.pred: underflow" else x `primIntSub` 1 toEnum x = x fromEnum x = x enumFrom n = eftInt n maxInt enumFromThen x1 x2 | x2 `primIntGE` x1 = efttIntUp x1 x2 maxInt | otherwise = efttIntDown x1 x2 minInt enumFromTo = eftInt enumFromThenTo x1 x2 y | x2 `primIntGE` x1 = efttIntUp x1 x2 y | otherwise = efttIntDown x1 x2 y minInt, maxInt :: Int minInt = primWordToInt ((primWordInv (0::Word) `primWordQuot` 2) `primWordAdd` 1) maxInt = primWordToInt (primWordInv (0::Word) `primWordQuot` 2)