{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# language TypeOperators #-}
{-# language TypeFamilies #-}
{-# language DataKinds #-}
{-# language MultiParamTypeClasses #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language DeriveGeneric #-}
{-# language QuantifiedConstraints #-}
{-# language UndecidableInstances #-}
module Generics.Kind.Examples where
import Data.PolyKinded.Functor
import GHC.Generics (Generic)
import GHC.TypeLits
import Type.Reflection
import Generics.Kind
instance GenericK Maybe (a ':&&: 'LoT0) where
type RepK Maybe = U1 :+: F V0
instance GenericK (Maybe a) LoT0 where
type RepK (Maybe a) = SubstRep (RepK Maybe) a
fromK = fromRepK
toK = toRepK
instance GenericK Either (a ':&&: b ':&&: LoT0) where
type RepK Either = F V0 :+: F V1
instance GenericK (Either a) (b ':&&: LoT0) where
type RepK (Either a) = SubstRep (RepK Either) a
fromK = fromRepK
toK = toRepK
instance GenericK (Either a b) LoT0 where
type RepK (Either a b) = SubstRep (RepK (Either a)) b
fromK = fromRepK
toK = toRepK
data Tree a = Branch (Tree a) (Tree a) | Leaf a
deriving Generic
instance GenericK Tree (a ':&&: 'LoT0) where
type RepK Tree = F (Tree :$: V0) :*: F (Tree :$: V0) :+: F V0
instance GenericK (Tree a) LoT0 where
type RepK (Tree a) = SubstRep (RepK Tree) a
fromK = fromRepK
toK = toRepK
data family HappyFamily t
data instance HappyFamily (Maybe a) = HFM Bool
data instance HappyFamily [a] = HFL a
instance GenericK HappyFamily (a ':&&: 'LoT0) where
type RepK HappyFamily = TypeError (Text "Cannot describe this family uniformly")
fromK = undefined
toK = undefined
instance GenericK (HappyFamily (Maybe a)) 'LoT0 where
type RepK (HappyFamily (Maybe a)) = F (Kon Bool)
fromK (HFM x) = F x
toK (F x) = HFM x
instance GenericK (HappyFamily [a]) 'LoT0 where
type RepK (HappyFamily [a]) = F (Kon a)
fromK (HFL x) = F x
toK (F x) = HFL x
data WeirdTree a where
WeirdBranch :: WeirdTree a -> WeirdTree a -> WeirdTree a
WeirdLeaf :: Show a => t -> a -> WeirdTree a
instance GenericK WeirdTree (a ':&&: 'LoT0) where
type RepK WeirdTree
= F (WeirdTree :$: V0) :*: F (WeirdTree :$: V0)
:+: E ((Show :$: V1) :=>: (F V0 :*: F V1))
fromK (WeirdBranch l r) = L1 $ F l :*: F r
fromK (WeirdLeaf a x) = R1 $ E $ C $ F a :*: F x
toK (L1 (F l :*: F r)) = WeirdBranch l r
toK (R1 (E (C (F a :*: F x)))) = WeirdLeaf a x
data WeirdTreeR a where
WeirdBranchR :: WeirdTreeR a -> WeirdTreeR a -> WeirdTreeR a
WeirdLeafR :: (Show a, Eq t, Typeable t) => t -> a -> WeirdTreeR a
instance GenericK WeirdTreeR (a ':&&: 'LoT0) where
type RepK WeirdTreeR
= F (WeirdTreeR :$: V0) :*: F (WeirdTreeR :$: V0)
:+: E (((Show :$: V1) :&: (Eq :$: V0) :&: (Typeable :$: V0)) :=>: (F V0 :*: F V1))
fromK (WeirdBranchR l r) = L1 $ F l :*: F r
fromK (WeirdLeafR a x) = R1 $ E $ C $ F a :*: F x
toK (L1 (F l :*: F r)) = WeirdBranchR l r
toK (R1 (E (C (F a :*: F x)))) = WeirdLeafR a x
instance GenericK (WeirdTreeR a) 'LoT0 where
type RepK (WeirdTreeR a)
= F (Kon (WeirdTreeR a)) :*: F (Kon (WeirdTreeR a))
:+: E ((Kon (Show a) :&: (Eq :$: V0) :&: (Typeable :$: V0)) :=>: ((F V0 :*: F (Kon a))))
fromK (WeirdBranchR l r) = L1 $ F l :*: F r
fromK (WeirdLeafR a x) = R1 $ E $ C $ F a :*: F x
toK (L1 (F l :*: F r)) = WeirdBranchR l r
toK (R1 (E (C (F a :*: F x)))) = WeirdLeafR a x