module Generics.Instant.Functions.Enum (
GEnum(..), genum
) where
import Generics.Instant.Base
import Generics.Instant.Instances ()
class GEnum a where
genum' :: [a]
instance GEnum U where
genum' = [U]
instance (GEnum a) => GEnum (Rec a) where
genum' = map Rec genum'
instance (GEnum a) => GEnum (Var a) where
genum' = map Var genum'
instance (GEnum a) => GEnum (CEq c p p a) where genum' = map C genum'
instance GEnum (CEq c p q a) where genum' = []
instance (GEnum f, GEnum g) => GEnum (f :+: g) where
genum' = map L genum' ||| map R genum'
instance (GEnum f, GEnum g) => GEnum (f :*: g) where
genum' = diag (map (\x -> map (\y -> x :*: y) genum') genum')
instance GEnum Int where
genum' = [0..9]
genum :: (Representable a, GEnum (Rep a)) => [a]
genum = map to genum'
infixr 5 |||
(|||) :: [a] -> [a] -> [a]
[] ||| ys = ys
(x:xs) ||| ys = x : ys ||| xs
diag :: [[a]] -> [a]
diag = concat . foldr skew [] . map (map (\x -> [x]))
skew :: [[a]] -> [[a]] -> [[a]]
skew [] ys = ys
skew (x:xs) ys = x : combine (++) xs ys
combine :: (a -> a -> a) -> [a] -> [a] -> [a]
combine _ xs [] = xs
combine _ [] ys = ys
combine f (x:xs) (y:ys) = f x y : combine f xs ys