module Data.Enum.Circular (csucc, cpred, Circular(..)) where
csucc :: (Eq a, Enum a, Bounded a) => a -> a
csucc :: forall a. (Eq a, Enum a, Bounded a) => a -> a
csucc = Circular a -> a
forall a. Circular a -> a
unCircular (Circular a -> a) -> (a -> Circular a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Circular a -> Circular a
forall a. Enum a => a -> a
succ (Circular a -> Circular a) -> (a -> Circular a) -> a -> Circular a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Circular a
forall a. a -> Circular a
Circular
cpred :: (Eq a, Enum a, Bounded a) => a -> a
cpred :: forall a. (Eq a, Enum a, Bounded a) => a -> a
cpred = Circular a -> a
forall a. Circular a -> a
unCircular (Circular a -> a) -> (a -> Circular a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Circular a -> Circular a
forall a. Enum a => a -> a
pred (Circular a -> Circular a) -> (a -> Circular a) -> a -> Circular a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Circular a
forall a. a -> Circular a
Circular
newtype Circular a = Circular {forall a. Circular a -> a
unCircular :: a}
deriving (Int -> Circular a -> ShowS
[Circular a] -> ShowS
Circular a -> String
(Int -> Circular a -> ShowS)
-> (Circular a -> String)
-> ([Circular a] -> ShowS)
-> Show (Circular a)
forall a. Show a => Int -> Circular a -> ShowS
forall a. Show a => [Circular a] -> ShowS
forall a. Show a => Circular a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Circular a -> ShowS
showsPrec :: Int -> Circular a -> ShowS
$cshow :: forall a. Show a => Circular a -> String
show :: Circular a -> String
$cshowList :: forall a. Show a => [Circular a] -> ShowS
showList :: [Circular a] -> ShowS
Show, Circular a -> Circular a -> Bool
(Circular a -> Circular a -> Bool)
-> (Circular a -> Circular a -> Bool) -> Eq (Circular a)
forall a. Eq a => Circular a -> Circular a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Circular a -> Circular a -> Bool
== :: Circular a -> Circular a -> Bool
$c/= :: forall a. Eq a => Circular a -> Circular a -> Bool
/= :: Circular a -> Circular a -> Bool
Eq)
instance (Enum a, Bounded a) => Enum (Circular a) where
toEnum :: Int -> Circular a
toEnum :: Int -> Circular a
toEnum = a -> Circular a
forall a. a -> Circular a
Circular (a -> Circular a) -> (Int -> a) -> Int -> Circular a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a
forall a. Enum a => Int -> a
toEnum (Int -> a) -> (Int -> Int) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len)
where len :: Int
len = a -> Int
forall a. Enum a => a -> Int
fromEnum (a
forall a. Bounded a => a
maxBound :: a) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
fromEnum :: Circular a -> Int
fromEnum :: Circular a -> Int
fromEnum = a -> Int
forall a. Enum a => a -> Int
fromEnum (a -> Int) -> (Circular a -> a) -> Circular a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Circular a -> a
forall a. Circular a -> a
unCircular
enumFromTo :: Circular a -> Circular a -> [Circular a]
enumFromTo :: Circular a -> Circular a -> [Circular a]
enumFromTo Circular a
start Circular a
end = (Int -> Circular a) -> [Int] -> [Circular a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Circular a
forall a. Enum a => Int -> a
toEnum ([Int] -> [Circular a]) -> [Int] -> [Circular a]
forall a b. (a -> b) -> a -> b
$ Int -> Int -> [Int]
forall a. Enum a => a -> a -> [a]
enumFromTo Int
i (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dist)
where i :: Int
i = Circular a -> Int
forall a. Enum a => a -> Int
fromEnum Circular a
start
j :: Int
j = Circular a -> Int
forall a. Enum a => a -> Int
fromEnum Circular a
end
dist :: Int
dist = (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len
len :: Int
len = a -> Int
forall a. Enum a => a -> Int
fromEnum (a
forall a. Bounded a => a
maxBound :: a) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
enumFromThenTo :: Circular a -> Circular a -> Circular a -> [Circular a]
enumFromThenTo :: Circular a -> Circular a -> Circular a -> [Circular a]
enumFromThenTo Circular a
from Circular a
next Circular a
to
| Int
step Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Circular a -> [Circular a]
forall a. a -> [a]
repeat Circular a
from
| Bool
otherwise = (Int -> Circular a) -> [Int] -> [Circular a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Circular a
forall a. Enum a => Int -> a
toEnum ([Int] -> [Circular a]) -> [Int] -> [Circular a]
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> [Int]
forall a. Enum a => a -> a -> a -> [a]
enumFromThenTo Int
i (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
step) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dist)
where i :: Int
i = Circular a -> Int
forall a. Enum a => a -> Int
fromEnum Circular a
from
j :: Int
j = Circular a -> Int
forall a. Enum a => a -> Int
fromEnum Circular a
next
k :: Int
k = Circular a -> Int
forall a. Enum a => a -> Int
fromEnum Circular a
to
step :: Int
step = (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len
dist :: Int
dist = (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
len
len :: Int
len = a -> Int
forall a. Enum a => a -> Int
fromEnum (a
forall a. Bounded a => a
maxBound :: a) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1