问题时,混合型类和类型的家庭
-
25-09-2019 - |
题
这个代码汇编罚款:
{-# 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手册。
您可以修复它的唯一途径是重构,从而不再需要它弄好了。
不隶属于 StackOverflow