{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
module Data.Universe.Generic where
import GHC.Generics
import Data.Universe.Class
import Data.Universe.Helpers
class GUniverse f where
guniverse :: [f a]
instance GUniverseSum f => GUniverse (M1 i c f) where
guniverse = map M1 $ interleave $ guniverseSum
class GUniverseSum f where
guniverseSum :: [[f a]]
instance GUniverseSum V1 where
guniverseSum = []
instance (GUniverseSum f, GUniverseSum g) => GUniverseSum (f :+: g) where
guniverseSum = map (map L1) guniverseSum ++ map (map R1) guniverseSum
instance GUniverseProduct f => GUniverseSum (M1 i c f) where
guniverseSum = [map M1 guniverseProduct]
class GUniverseProduct f where
guniverseProduct :: [f a]
instance GUniverseProduct U1 where
guniverseProduct = [U1]
instance (GUniverseProduct f, GUniverseProduct g) => GUniverseProduct (f :*: g) where
guniverseProduct = cartesianProduct (:*:) guniverseProduct guniverseProduct
instance GUniverseProduct f => GUniverseProduct (M1 i c f) where
guniverseProduct = map M1 guniverseProduct
instance Universe a => GUniverseProduct (K1 r a) where
guniverseProduct = map K1 universe
universeGeneric :: (Generic a, GUniverse (Rep a)) => [a]
universeGeneric = map to guniverse