Generic.hs (3959B)
1 {-# LANGUAGE UndecidableInstances #-} 2 {-# LANGUAGE UndecidableSuperClasses #-} 3 4 module Lude.Haskell.Generic ( 5 Generic (..), 6 Generic1 (..), 7 Genericity (..), 8 grep, 9 Generically, 10 Genericity1 (..), 11 grep1, 12 Generically1, 13 GVoid, 14 elimGVoid, 15 GUnit, 16 pattern MkGUnit, 17 elimGUnit, 18 GConst, 19 pattern MkGConst, 20 unGConst, 21 GMeta, 22 pattern MkGMeta, 23 unGMeta, 24 GSum, 25 pattern GLeft, 26 pattern GRight, 27 elimGSum, 28 GProd, 29 pattern GPair, 30 elimGProd, 31 ) where 32 33 import GHC.Generics (Generic, Generic1) 34 import GHC.Generics qualified as G 35 36 import Lude.Haskell.Constraint 37 import Lude.Haskell.Core 38 import Lude.Haskell.Functional 39 import Lude.Haskell.Type 40 41 -------------------------------------------------------------------------------- 42 43 type Genericity :: Endo Type 44 newtype Genericity a = MkGenericity {unGenericity :: a} 45 46 grep :: forall (a :: Type). (Generic a) => Genericity a -> G.Rep a a 47 grep (MkGenericity x) = G.from x 48 49 type Generically :: Endo (Type -> Constraint) 50 class (Generic a, c (G.Rep a a)) => Generically c a 51 instance (Generic a, c (G.Rep a a)) => Generically c a 52 53 -------------------------------------------------------------------------------- 54 55 type Genericity1 :: forall {k}. Endo (k -> Type) 56 newtype Genericity1 f p = MkGenericity1 {unGenericity1 :: f p} 57 58 grep1 :: forall {k} (f :: k -> Type) (p :: k). (Generic1 f) => Genericity1 f p -> G.Rep1 f p 59 grep1 (MkGenericity1 x) = G.from1 x 60 61 type Generically1 :: forall {k}. Endo ((k -> Type) -> Constraint) 62 class (Generic1 f, c (G.Rep1 f)) => Generically1 c f 63 instance (Generic1 f, c (G.Rep1 f)) => Generically1 c f 64 65 -------------------------------------------------------------------------------- 66 67 type GVoid = G.V1 68 69 elimGVoid :: forall {k} (p :: k) {r :: Repr} (b :: Type# r). GVoid p -> b 70 elimGVoid = \case {} 71 {-# INLINE elimGVoid #-} 72 73 -------------------------------------------------------------------------------- 74 75 type GUnit = G.U1 76 77 pattern MkGUnit :: forall {k} (p :: k). GUnit p 78 pattern MkGUnit = G.U1 79 {-# COMPLETE MkGUnit #-} 80 81 elimGUnit :: forall {k} (p :: k) {r :: Repr} (b :: Type# r). Lev b -> (GUnit p -> b) 82 elimGUnit unit = \MkGUnit -> unit 83 {-# INLINE elimGUnit #-} 84 85 -------------------------------------------------------------------------------- 86 87 type GConst = G.K1 88 89 pattern MkGConst :: forall {k} i (a :: Type) (p :: k). a -> GConst i a p 90 pattern MkGConst x = G.K1 x 91 {-# COMPLETE MkGConst #-} 92 93 unGConst :: forall {k} i (a :: Type) (p :: k). GConst i a p -> a 94 unGConst = G.unK1 95 96 -------------------------------------------------------------------------------- 97 98 type GMeta = G.M1 99 100 pattern MkGMeta :: forall {k} i (m :: G.Meta) (f :: k -> Type) (p :: k). f p -> GMeta i m f p 101 pattern MkGMeta x = G.M1 x 102 {-# COMPLETE MkGMeta #-} 103 104 unGMeta :: forall {k} i (m :: G.Meta) (f :: k -> Type) (p :: k). GMeta i m f p -> f p 105 unGMeta = G.unM1 106 107 -------------------------------------------------------------------------------- 108 109 type GSum = (G.:+:) 110 111 pattern GLeft :: forall {k} (f :: k -> Type) (g :: k -> Type) (p :: k). f p -> GSum f g p 112 pattern GLeft x = G.L1 x 113 pattern GRight :: forall {k} (f :: k -> Type) (g :: k -> Type) (p :: k). g p -> GSum f g p 114 pattern GRight y = G.R1 y 115 {-# COMPLETE GLeft, GRight #-} 116 117 elimGSum 118 :: forall {k} (f :: k -> Type) (g :: k -> Type) (p :: k) {r :: Repr} (b :: Type# r) 119 . (f p -> b) -> (g p -> b) -> (GSum f g p -> b) 120 elimGSum left right = \case 121 GLeft x -> left x 122 GRight y -> right y 123 {-# INLINE elimGSum #-} 124 125 -------------------------------------------------------------------------------- 126 127 type GProd = (G.:*:) 128 129 pattern GPair :: forall {k} (f :: k -> Type) (g :: k -> Type) (p :: k). f p -> g p -> GProd f g p 130 pattern GPair x y = x G.:*: y 131 {-# COMPLETE GPair #-} 132 133 elimGProd 134 :: forall {k} (f :: k -> Type) (g :: k -> Type) (p :: k) {r :: Repr} (b :: Type# r) 135 . (f p -> g p -> b) -> (GProd f g p -> b) 136 elimGProd pair = \(GPair x y) -> pair x y 137 {-# INLINE elimGProd #-}