{-# language GHC2024, AllowAmbiguousTypes, TypeAbstractions #-} import Data.Maybe import Data.Type.Equality import GHC.TypeLits import System.Environment main = do [s] <- getArgs putStrLn $ fromMaybe "some default value" $ dispatchDyn s class Dispatchable d where dispatch :: String instance Dispatchable "a" where dispatch = "A" instance Dispatchable "b" where dispatch = "B" dispatchDyn :: String -> Maybe String dispatchDyn m = withSomeSSymbol m $ \(SSymbol @m) -> case stringDispatchable @m of Just Dict -> Just $ dispatch @m Nothing -> Nothing stringDispatchable :: KnownSymbol m => Maybe (Dict (Dispatchable m)) stringDispatchable @m | Just Refl <- is @"a" @m = Just Dict | Just Refl <- is @"b" @m = Just Dict | otherwise = Nothing where is :: (KnownSymbol a, KnownSymbol b) => Maybe (a :~: b) is @a @b = sameSymbol (SSymbol @a) (SSymbol @b) data Dict c = c => Dict