{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wno-orphans #-} module Worksheets.Utils.Generics ( module Worksheets.Utils.Generics, module GHC.Generics, ) where import Data.Char qualified as Char import GHC.Generics import Prelude (Eq (..), Maybe (..), String, otherwise, (<>)) -- | Cut the first lowercases, and lowercase the first uppercase. dropLowercasesAndLowerNextChar :: String -> String dropLowercasesAndLowerNextChar "" = "" dropLowercasesAndLowerNextChar (c : cs) | Char.isUpper c = Char.toLower c : cs | otherwise = dropLowercasesAndLowerNextChar cs -- | Cut the first lowercases, and lowercase the first uppercase. dropUntilUnderscore :: String -> String dropUntilUnderscore "" = "" dropUntilUnderscore (c : cs) | c == '_' = cs | otherwise = dropUntilUnderscore cs class DataSelectorNames f where -- | List the names of the selectors of a data type. dataSelectorNames :: [String] instance DataSelectorNames (Rep a ()) => DataSelectorNames (Generically a) where dataSelectorNames = dataSelectorNames @(Rep a ()) {- instance (DataSelectorNames f) => DataSelectorNames (M1 D t f) where dataSelectorNames = dataSelectorNames @f instance (DataSelectorNames f, DataSelectorNames g) => DataSelectorNames (f :+: g) where dataSelectorNames = dataSelectorNames @f <> dataSelectorNames @g instance DataSelectorNames (C1 c f) where dataSelectorNames = [conName (undefined :: C1 c f g)] -} deriving instance DataSelectorNames c => DataSelectorNames (K1 i c p) deriving instance DataSelectorNames p => DataSelectorNames (Par1 p) deriving instance DataSelectorNames (f p) => DataSelectorNames (Rec1 f p) -- instance DataSelectorNames (f p) => DataSelectorNames (M1 i c f p) where dataSelectorNames = dataSelectorNames @(f p) instance (DataSelectorNames (f p), DataSelectorNames (g p)) => DataSelectorNames ((f :*: g) p) where dataSelectorNames = dataSelectorNames @(f p) <> dataSelectorNames @(g p) deriving instance DataSelectorNames (f (g p)) => DataSelectorNames ((f :.: g) p) instance DataSelectorNames (f p) => DataSelectorNames (M1 D (MetaData typeName moduleName packageName isNewtype) f p) where dataSelectorNames = dataSelectorNames @(f p) instance DataSelectorNames (f p) => DataSelectorNames (M1 C (MetaCons consName consFixity consHasRecordSelectors) f p) where dataSelectorNames = dataSelectorNames @(f p) instance Selector (MetaSel (Just selName) selUnpackedness selStrictness selStrictnessInferred) => DataSelectorNames (M1 S (MetaSel (Just selName) selUnpackedness selStrictness selStrictnessInferred) f p) where dataSelectorNames = [selName n] where n :: M1 S (MetaSel (Just selName) selUnpackedness selStrictness selStrictnessInferred) f p n = n