ref: cb7ae3b919c7ab22cd6cb6003b6b63a5931a6402
dir: /lib/Data/Enum.hs/
module Data.Enum(module Data.Enum) where
import Prelude() -- do not import Prelude
import Primitives
import Control.Error
import Data.Bool
import Data.Char_Type
import Data.Bounded
import Data.Function
import Data.Int
import Data.List
import Data.Num
import Data.Ord
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 . (+ 1) . fromEnum
pred = toEnum . (subtract 1) . fromEnum
enumFrom x = map toEnum [fromEnum x ..]
enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..]
enumFromTo x y = map toEnum [fromEnum x .. fromEnum y]
enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]
boundedEnumFrom :: forall a . (Enum a, Bounded a) => a -> [a]
boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)]
boundedEnumFromThen :: forall a . (Enum a, Bounded a) => a -> a -> [a]
boundedEnumFromThen n1 n2
| i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)]
| otherwise = map toEnum [i_n1, i_n2 .. fromEnum (minBound `asTypeOf` n1)]
where
i_n1 = fromEnum n1
i_n2 = fromEnum n2
-- This instance is difficult to put in Data.Int,
-- so it gets to live here.
instance Enum Int where
succ x = x + 1
pred x = x - 1
toEnum x = x
fromEnum x = x
enumFrom n = n : enumFrom (n+1)
enumFromThen n m = from n
where d = m - n
from i = i : from (i+d)
enumFromTo l h = takeWhile (<= h) (enumFrom l)
enumFromThenTo l m h =
if m > l then
takeWhile (<= h) (enumFromThen l m)
else
takeWhile (>= h) (enumFromThen l m)
-- Likewise for Bool
instance Enum Bool where
fromEnum False = 0
fromEnum True = 1
toEnum i = if primIntEQ i (0::Int) then False else
if primIntEQ i (1::Int) then True else
error "Enum.Bool.toEnum: bad arg"
instance Enum Char where
fromEnum = primOrd
toEnum = primChr
instance Enum Ordering where
fromEnum LT = (0::Int)
fromEnum EQ = (1::Int)
fromEnum GT = (2::Int)
toEnum i = if i `primIntEQ` 0 then LT
else if i `primIntEQ` 1 then EQ
else if i `primIntEQ` 2 then GT
else error "Ord.toEnum: out of range"