#gradle #kotlin #kapt #arrow-kt
#gradle #kotlin #капт #стрелка-kt
Вопрос:
Я определяю два объекта:
data class ParserK
аннотировано@higherkind
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
Вот что я обнаружил:
- Если я удалю определение функтора, то цель успешно завершится, и я смогу увидеть сгенерированный код.
- Если я удалю
@higherkind
из класса данныхParserK
и скопирую сгенерированные источники в тот же файл, гдеParserK
определен, я смогу увидеть сгенерированный код для функтора.
Для меня это похоже на ошибку, поправьте меня, если я ошибаюсь, пожалуйста
ОБНОВЛЕНО:
- Вот ссылка на репозиторий с моим кодом: репозиторий
- Проблема с отслеживателем ошибок здесь
Комментарии:
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. Это означает, что в будущих выпусках эта проблема будет решена.