{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# language TypeOperators #-}
{-# language TypeFamilies #-}
{-# language DataKinds #-}
{-# language PolyKinds #-}
{-# language MultiParamTypeClasses #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language DeriveGeneric #-}
{-# language QuantifiedConstraints #-}
{-# language UndecidableInstances #-}
{-# language RankNTypes #-}
{-# language UnboxedTuples #-}
module Generics.Kind.Examples where
import Data.PolyKinded.Functor
import GHC.Generics (Generic)
import GHC.TypeLits
import Type.Reflection (Typeable)
import Data.Proxy
import Generics.Kind
instance GenericK Maybe where
type RepK Maybe = U1 :+: Field Var0
instance GenericK (Maybe a) where
type RepK (Maybe a) = SubstRep (RepK Maybe) a
fromK = fromRepK
toK = toRepK
instance GenericK [] where
type RepK [] = U1 :+: Field Var0 :*: Field ([] :$: Var0)
instance GenericK [a] where
type RepK [a] = SubstRep (RepK []) a
fromK = fromRepK
toK = toRepK
instance GenericK Either where
type RepK Either = Field Var0 :+: Field Var1
instance GenericK (Either a) where
type RepK (Either a) = SubstRep (RepK Either) a
fromK = fromRepK
toK = toRepK
instance GenericK (Either a b) 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 where
type RepK Tree = Field (Tree :$: Var0) :*: Field (Tree :$: Var0) :+: Field Var0
instance GenericK (Tree a) 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 where
type RepK HappyFamily = TypeError (Text "Cannot describe this family uniformly")
fromK = undefined
toK = undefined
instance GenericK (HappyFamily (Maybe a)) where
type RepK (HappyFamily (Maybe a)) = Field (Kon Bool)
fromK (HFM x) = Field x
toK (Field x) = HFM x
instance GenericK (HappyFamily [a]) where
type RepK (HappyFamily [a]) = Field (Kon a)
fromK (HFL x) = Field x
toK (Field x) = HFL x
data SimpleIndex :: * -> * -> * where
MkSimpleIndex :: [a] -> SimpleIndex [a] b
instance GenericK SimpleIndex where
type RepK SimpleIndex
= Exists (*) ((Var1 :~: ([] :$: Var0)) :=>: Field ([] :$: Var0))
fromK (MkSimpleIndex x) = Exists (SuchThat (Field x))
toK (Exists (SuchThat (Field x))) = (MkSimpleIndex x)
instance GenericK (SimpleIndex a) where
type RepK (SimpleIndex a)
= Exists (*) ((Kon a :~: ([] :$: Var0)) :=>: Field ([] :$: Var0))
fromK (MkSimpleIndex x) = Exists (SuchThat (Field x))
toK (Exists (SuchThat (Field x))) = (MkSimpleIndex x)
instance GenericK (SimpleIndex a b) where
type RepK (SimpleIndex a b)
= Exists (*) ((Kon a :~: ([] :$: Var0)) :=>: Field ([] :$: Var0))
fromK (MkSimpleIndex x) = Exists (SuchThat (Field x))
toK (Exists (SuchThat (Field x))) = (MkSimpleIndex x)
data WeirdTree a where
WeirdBranch :: WeirdTree a -> WeirdTree a -> WeirdTree a
WeirdLeaf :: Show a => t -> a -> WeirdTree a
instance GenericK WeirdTree where
type RepK WeirdTree
= Field (WeirdTree :$: Var0) :*: Field (WeirdTree :$: Var0)
:+: Exists (*) ((Show :$: Var1) :=>: (Field Var0 :*: Field Var1))
fromK (WeirdBranch l r) = L1 $ Field l :*: Field r
fromK (WeirdLeaf a x) = R1 $ Exists $ SuchThat $ Field a :*: Field x
toK (L1 (Field l :*: Field r)) = WeirdBranch l r
toK (R1 (Exists (SuchThat (Field a :*: Field 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 where
type RepK WeirdTreeR
= Field (WeirdTreeR :$: Var0) :*: Field (WeirdTreeR :$: Var0)
:+: Exists (*) (((Show :$: Var1) :&: (Eq :$: Var0) :&: (Typeable :$: Var0))
:=>: (Field Var0 :*: Field Var1))
fromK (WeirdBranchR l r) = L1 $ Field l :*: Field r
fromK (WeirdLeafR a x) = R1 $ Exists $ SuchThat $ Field a :*: Field x
toK (L1 (Field l :*: Field r)) = WeirdBranchR l r
toK (R1 (Exists (SuchThat (Field a :*: Field x)))) = WeirdLeafR a x
instance GenericK (WeirdTreeR a) where
type RepK (WeirdTreeR a)
= Field (Kon (WeirdTreeR a)) :*: Field (Kon (WeirdTreeR a))
:+: Exists (*) ((Kon (Show a) :&: (Eq :$: Var0) :&: (Typeable :$: Var0))
:=>: ((Field Var0 :*: Field (Kon a))))
fromK (WeirdBranchR l r) = L1 $ Field l :*: Field r
fromK (WeirdLeafR a x) = R1 $ Exists $ SuchThat $ Field a :*: Field x
toK (L1 (Field l :*: Field r)) = WeirdBranchR l r
toK (R1 (Exists (SuchThat (Field a :*: Field x)))) = WeirdLeafR a x
data TTY m a where
WriteTTY :: String -> TTY m ()
ReadTTY :: TTY m String
instance GenericK (TTY m a) where
type RepK (TTY m a)
= ((Kon a :~: Kon ()) :=>: Field (Kon String))
:+: ((Kon a :~: Kon String) :=>: U1)
fromK (WriteTTY s) = L1 (SuchThat (Field s))
fromK ReadTTY = R1 (SuchThat U1)
toK (L1 (SuchThat (Field s))) = WriteTTY s
toK (R1 (SuchThat U1)) = ReadTTY
data T (a :: k) where
MkT :: forall (a :: *). Maybe a -> T a
instance GenericK (T :: k -> *) where
type RepK (T :: k -> *) =
Exists (*) ((Kon (k ~ (*)) :&: (Var0 :~~: Var1)) :=>: Field (Maybe :$: Var0))
fromK (MkT x) = Exists (SuchThat (Field x))
toK (Exists (SuchThat (Field x))) = MkT x
data P k (a :: k) where
P :: forall k (a :: k). P k a
instance GenericK (P k) where
type RepK (P k) = U1
fromK P = U1
toK U1 = P
data P' j (a :: k) where
P' :: forall k (a :: k). P' k a
instance GenericK (P' j :: k -> *) where
type RepK (P' j :: k -> *) = (Kon k :~: Kon j) :=>: U1
fromK P' = SuchThat U1
toK (SuchThat U1) = P'
instance GenericK (P' :: * -> k -> *) where
type RepK (P' :: * -> k -> *) = (Kon k :~: Var0) :=>: U1
fromK P' = SuchThat U1
toK (SuchThat U1) = P'
data Ranky = MkRanky (forall a. a -> a)
instance GenericK Ranky where
type RepK Ranky = Field (ForAll ((->) :$: Var0 :@: Var0))
fromK (MkRanky x) = Field (ForAllI x)
toK (Field (ForAllI x)) = MkRanky x
newtype Ranky2 b = MkRanky2 ((forall a. a -> a) -> b)
instance GenericK Ranky2 where
type RepK Ranky2 = Field ((->) :$: ForAll ((->) :$: Var0 :@: Var0) :@: Var0)
fromK (MkRanky2 f) = Field (\(ForAllI x) -> f x)
toK (Field f) = MkRanky2 (\x -> f (ForAllI x))
data Shower a where
MkShower :: (Show a => a -> String) -> Shower a
instance GenericK Shower where
type RepK Shower = Field ((Show :$: Var0) :=>>: ((->) :$: Var0 :@: Kon String))
fromK (MkShower f) = Field (SuchThatI f)
toK (Field (SuchThatI f)) = MkShower f
data Unboxed1 = MkUnboxed1 (# Int, Int #)