"非法型同义词家族"的解释

gat*_*ado 9 haskell typeclass

我只是好奇为什么要写这个,

instance (HzMonad , Data.Suitable.Suitable  ?, ? ~ ExprTyp  ?) => VarDecl  ? where
    var = varhz
Run Code Online (Sandbox Code Playgroud)

而不是这个

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  ?)'
Run Code Online (Sandbox Code Playgroud)

哪里

varhz ::
  (HzMonad , Data.Suitable.Suitable  ?) =>
  String -> ExprTyp  ? ->  (ExprTyp  ?)
Run Code Online (Sandbox Code Playgroud)

什么是波浪号呢?非常感谢.

gat*_*ado 3

我认为问题在于 \n \n 右侧的所有内容都=>必须是类型构造函数或类型变量。ExprTyp 可以引用多个不同类型的构造函数。用等式约束替换它确实可行,但生成的实例实际上是无用的,因为编译器将无法推断出任何关于\xce\xb3它的 ExprTyp 的信息——ExprTyp 可以是任何东西的别名。

\n\n

在我的情况下——我正在尝试编写一个 DSL monad——解决方案是将关联类型的所有使用包装在新类型构造函数中。例如,如果我们从以下开始:

\n\n
class MyDSL m a where\n    type ExprTyp m :: * -> *\n    printE :: ExprTyp m a -> m ()\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后包装这将导致

\n\n
newtype ExprT a = ExprT a\nclass MyDSL m a where\n    type ExprTyp m :: * -> *\n    printE :: ExprT (ExprTyp m a) -> m ()\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,例如,变量声明(我正在为元组变量声明编写代码)可以是,

\n\n
instance (HzMonad , Data.Suitable.Suitable  \xce\xb1, \xce\xb3 ~ ExprTyp  \xce\xb1) => VarDecl  (ExprT \xce\xb3)\ninstance (Monad , VarDecl  \xce\xb1, VarDecl  \xce\xb2) => VarDecl  (\xce\xb1, \xce\xb2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果有不清楚的地方,请发表评论。

\n