Невозможно сгенерировать объекты для @higherkind и @extension - PullRequest
1 голос
/ 22 апреля 2019

Я определяю два объекта:

  1. data class ParserK с комментариями @higherkind
  2. interface ParserKFunctor с комментариями @extension

Здеськод:

@higherkind
data class ParserK<A>(val f: (String) -> Option<A>): ParserKOf<A> {
    companion object
}

@extension
interface ParserKFunctor : Functor<ForParserK> {
    override fun <A, B> Kind<ForParserK, A>.map(f: (A) -> B): Kind<ForParserK, B> {
        ...
    }
}

Когда я выполняю ./gradlew :app:kaptKotlin, я получаю:

error: "Arrow's annotations can only be used on Kotlin classes". Not valid for error.NonExistentClass

> Task :app:kaptGenerateStubsKotlin

> Task :app:kaptKotlin FAILED
e: error: Arrow's annotations can only be used on Kotlin classes. Not valid for error.NonExistentClass                                           

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:kaptKotlin'.
> Compilation error. See log for more details

Вот что я обнаружил:

  1. Если я уберу функторопределение, то цель успешно завершена, и я вижу сгенерированный код.
  2. Если я удаляю @higherkind из класса данных ParserK и копирую сгенерированные источники в тот же файл, где определено ParserK, то яможет видеть сгенерированный код для функтора.

Мне кажется, что это ошибка, исправьте меня, если я ошибаюсь, пожалуйста

ОБНОВЛЕНО:

  1. Вот ссылка на репозиторий с моим кодом: репозиторий
  2. Проблема с трекером ошибок здесь

1 Ответ

1 голос
/ 16 июня 2019

(для версии со стрелкой 0.9.1-SNAPSHOT и более ранних версий)

У процессоров Higherkinded Processor и Extension Processor есть зависимость.Правильно, аннотация расширения зависит от кода, сгенерированного аннотацией с более высоким номеромЗачем проверять эту ссылку .

Краткое резюме: всякий раз, когда вы пытаетесь реализовать классы типов, компилятору нужны типы данных Higherkinded для вашего типа данных.

@extension
interface ListKFunctor : Functor<ForListK> {
//                                ^^^^^^^^
//                    This exists after building your module
  override fun <A, B> Kind<ForListK, A>.map(f: (A) -> B): Kind<ForListK, B> {
    return this.fix().map(f)
  }
}

Простейший ответ на этот вопрос:

Always separate your Higherkinded Types from your typeclass definitions.

Но Эрроу экспериментирует с другими вариантами на Codegen.Смысл в будущих выпусках эта проблема будет решена.

...