{-# LANGUAGE TypeFamilies #-} import Data.Kind (Type) class TupArgs tup where type TupFun tup r :: Type applyTupFun :: TupFun tup r -> tup -> r instance TupArgs () where type TupFun () r = r applyTupFun x _ = x instance TupArgs (a, b) where type TupFun (a, b) r = a -> b -> r applyTupFun f (x, y) = f x y instance TupArgs (a, b, c) where type TupFun (a, b, c) r = a -> b -> c -> r applyTupFun f (x, y, z) = f x y z foo :: TupArgs tup => tup -> TupFun tup r -> r foo tup f = applyTupFun f tup ver :: a -> a ver = id main :: IO () main = print $ foo (4 :: Int, ver 2) (\x y -> x + y)