请考虑以下代码: {-# LANGUAGE RankNTypes, MultiParamTypeClasses, FunctionalDependencies #-}data St t = St { use_t :: t }class S s t | s - t where -- Nothing reallynewtype P s = P { unP :: forall b t. (S s t) = St t - (St t - b) -- p
{-# LANGUAGE RankNTypes, MultiParamTypeClasses, FunctionalDependencies #-} data St t = St { use_t :: t } class S s t | s -> t where -- Nothing really newtype P s = P { unP :: forall b t. (S s t) => St t -> (St t -> b) -- pok -> b } f :: (S s t) => t -> P s f t = P $\s pok -> pok s { use_t = t }
代码看起来很人为,但是想法是类S用于表示类型参数t由类型参数s确定,所以我不必将类型参数添加到类型P中.
然而,上述代码简短地给出了以下错误:不能从上下文(S s t)或(S s t1)推导出(t1~t).此错误消息表明编译器想要使用这些上下文中的一个或另一个,而我希望它将使用它们并从它们结束t1~t.
我将不胜感激任何建议,无需添加t作为类型P的类型参数.
你不能用写的类来做.请参阅 Can I magic up type equality from a functional dependency?.但您可以使用其他类来执行此操作:class t ~ T s => S s t where type T s :: *
你需要为每个实例定义T,但至少这并不难.如果有合适的T,您可以提供T的默认定义.