I must say I don’t fully understand the purpose of the example given, but I do recall I used type families to “hide” “private information” in some other cases:
{-# LANGUAGE TypeFamilies #-}
import Data.Kind (Type)
data Crust = ThickCrust | ThinCrust
deriving (Show, Eq, Ord)
data PizzaComponent = Salami | AmericanCheese
deriving (Show, Eq, Ord)
data Pizza = Pizza Crust [PizzaComponent]
deriving (Show, Eq, Ord)
data Meal
= PreparedPizza Pizza
-- | PreparedSandwich Sandwich
deriving (Show, Eq, Ord)
class Monad m => CPizzaRecipe m where
class Monad m => CCookingMachine m where
type family PIZZA_RECIPE m :: Type -> Type
cmakePizza :: PIZZA_RECIPE m Pizza -> m Pizza
-- cmakeSandwitch :: CSandwichRecipe r => r Sandwich -> m Sandwich
cmakeRandomPizzaRceipe :: m (PIZZA_RECIPE m Pizza)
csampleCookingMachine
:: forall m
. CCookingMachine m
=> m [Meal]
csampleCookingMachine = do
rndPizzaRecipe <- cmakeRandomPizzaRceipe
rndPizza <- cmakePizza rndPizzaRecipe
pure [{-PreparedPizza pizza,-} PreparedPizza rndPizza]