这个代码汇编罚款:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

instance Sel a s (b->(c,a)) where
  type Res a s (b->(c,a)) = (b -> s -> (c,s))

但只要我加入R谓ghc失败:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

class R a where
  type Rec a :: *
  cons :: a -> Rec a
  elim :: Rec a -> a
instance Sel a s (b->(c,Rec a)) where
  type Res a s (b->(c,Rec a)) = (b -> s -> (c,s))

抱怨是:

    Illegal type synonym family application in instance:
        b -> (c, Rec a)
    In the instance declaration for `Sel a s (b -> (c, Rec a))'

它意味着什么以及(最重要的是)我怎么修它?

感谢

有帮助吗?

解决方案

类型的家庭是单向的:你可以扩展到Rec a其计算类型,但你不能(唯一)从扩展回到Rec a去。这使得型功能的应用不适合例如签名,因为它们不能触发实例适用。

您可以尝试,而不是:

instance Rec a ~ reca => Sel a s (b->(c,reca))

此装置别的东西:它说任何功能b -> (c, reca)是一个实例,并且然后当它不可撤销地相匹配时,编译器检查该Rec a ~ reca。但是,这可能是足够好你的情况做想。

其他提示

Rec 是不是一个种类的构造;它是一种类型的功能。也许你可以用它只有在种类型的值定义,而不是在一个类声明?我猜,疯狂地在这里;我不明白所有的规则类型的家庭。

我不知道如何解决这个问题,但一些东西尝试包括:

  • 摆脱类Sel,只是定义 type family Res a s b :: *.使用 type instance 而不是类机构。

  • 它几乎没有可能使类型 Rec 射使用 data 会有帮助,但我不这么认为。

  • 切回到最小数量的语言扩展可能的工作,它将使它更易为其他人帮助你,它可能会帮助编译器。

这意味着,你不能声明类型实例时使用类型synomym家庭。请参见 “类型的家庭和实例声明”的GHC手册

您可以修复它的唯一途径是重构,从而不再需要它弄好了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top