Невозможно сгенерировать объекты как для @higherkind, так и для @extension

#gradle #kotlin #kapt #arrow-kt

#gradle #kotlin #капт #стрелка-kt

Вопрос:

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

  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. У меня точно такая же проблема. Вы отправили сообщение о проблеме с arrow-kt?

2. @AleksandarDimitrov, мы нашли решение проблемы, не стесняйтесь проверять репозиторий на наличие ссылок.

Ответ №1:

(Для arrow-версии 0.9.1-SNAPSHOT и предыдущих)

Процессор с более высоким качеством и процессоры расширения имеют зависимость. Правильно, аннотация расширения зависит от кода, сгенерированного аннотацией 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.

Но Arrow экспериментирует с другими опциями в Codegen. Это означает, что в будущих выпусках эта проблема будет решена.