Можно ли получить экземпляр Generi c рекурсивного типа данных? - PullRequest
1 голос
/ 25 марта 2020

Я играю с некоторыми типами и компилятором 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 _

В качестве первого шага к экземпляру Show.

Затем средство проверки типов выдает эту ошибку:

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

Есть ли способ получить экземпляр Generi c из моего типа? Если нет, то есть ли способ написать экземпляр Generi c вручную? Я понятия не имею, что это повлечет за собой, поэтому я согласен с тем, что не уверен, что последний вопрос имеет смысл.

1 Ответ

2 голосов
/ 25 марта 2020

Конечно, можно получить Generic для вашего типа, вы просто не используете правильный синтаксис. Это должно быть так:

derive instance genericCommand :: Generic (Command a) _

Когда вы пишете Generic Command _, деталь Command (которая является первым параметром Generic) имеет вид Type -> Type - то есть, если вы применяете Command до Type, тогда вы получите Type. Так, например, Command Int будет иметь вид Type. Но Command сам по себе имеет вид Type -> Type.

Но класс Generic ожидает первый аргумент вида Type, а не Type -> Type, это то, что сообщается вам в сообщении об ошибке.

...