是否可以派生递归数据类型的通用实例?

Is it possible to derive a Generic instance of a recursive datatype?

我正在研究一些类型和 PureScript 编译器。这些是我创建的类型(从 purescript-dsl-example 中大量窃取):

newtype User = User
  { id :: Int
  , name :: String
  }

data Command a = Add User a
               | Remove Int a
               | ChangeName Int String a

该类型检查并编译。然后,认为能够将这些类型序列化为 JSON 可能很有用,我安装了 purescript-foreign-generic 并添加了这个:

derive instance genericCommand :: Generic Command _

作为展示实例的第一步。

然后类型检查器抛出这个错误:

Error found:
in module Main
at src/Main.purs:33:43 - 33:50 (line 33, column 43 - line 33, column 50)

  Could not match kind

    Type

  with kind

    Type -> Type


while checking the kind of Generic Command (Sum (Constructor "Add" (Product ... ...)) (Sum (Constructor "Remove" ...) (Constructor "ChangeName" ...)))
in value declaration genericCommand

有没有办法从我的类型中派生出通用实例?如果没有,有没有办法手动编写通用实例?我不知道那会带来什么,所以我承认我不确定最后一个问题是否有意义。

当然可以为您的类型导出 Generic,只是您没有使用正确的语法。应该是这样的:

derive instance genericCommand :: Generic (Command a) _

当你写 Generic Command _ 时,Command 部分(Generic 的第一个参数)有种类 Type -> Type - 也就是说,如果你应用 CommandType,然后你得到 Type。因此,例如,Command Int 将具有 Type 类型。但是 Command 本身有种类 Type -> Type.

但是 Generic class 需要第一个参数类型 Type,而不是 Type -> Type,这就是错误消息告诉您的内容。