我只是好奇为什么要写这个,
instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl γ where
var = varhz
而不是
instance (HzMonad , Data.Suitable.Suitable α) => VarDecl (ExprTyp α) where
var = varhz
-- error
Hz2/Language.hs:114:53:
Illegal type synonym family application in instance: ExprTyp α
In the instance declaration for `VarDecl (ExprTyp α)'
,其中
varhz ::
(HzMonad , Data.Suitable.Suitable α) =>
String -> ExprTyp α -> (ExprTyp α)
无论如何,波士顿是什么?非常感谢。
答案 0 :(得分:3)
我认为问题在于右侧的一切
=>
必须是类型构造函数或类型变量。 ExprTyp可以引用多个不同类型的构造函数。用相等约束替换它确实会起作用,但是生成的实例实际上是无用的,因为编译器将无法推断出γ
的任何内容,因为它是ExprTyp - ExprTyp可能被别名化。
在我的情况下 - 我正在尝试编写DSL monad - 解决方案是在newtype构造函数中包含相关类型的所有用法。例如,如果我们开始,
class MyDSL m a where
type ExprTyp m :: * -> *
printE :: ExprTyp m a -> m ()
然后将其包装将导致
newtype ExprT a = ExprT a
class MyDSL m a where
type ExprTyp m :: * -> *
printE :: ExprT (ExprTyp m a) -> m ()
然后,例如,变量声明(我正在为编组变量声明编写代码)可能是,
instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl (ExprT γ)
instance (Monad , VarDecl α, VarDecl β) => VarDecl (α, β)
如果不清楚,请发表评论。