无法为@higherkind 和@extension 生成对象

Unable to generate objects for both @higherkind and @extension

我定义了两个对象:

  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. 如果我从数据 class ParserK 中删除 @higherkind 并将生成的源代码复制到定义了 ParserK 的同一个文件中,那么我可以看到生成的代码对于函子。

这对我来说似乎是一个错误,如果我错了,请纠正我

更新:

  1. 这是 link 到存储库的代码:repository
  2. 错误跟踪器上的问题是 here

(对于 arrow-version 0.9.1-SNAPSHOT 及之前版本)

Higherkinded 处理器和扩展处理器具有依赖性。正确的是,扩展注解依赖于 higherkinded 注解生成的代码。为什么要检查这个 link

简短的总结是,每当您尝试实现类型类时,编译器都需要您的数据类型的高级类型。

@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 上试验其他选项。这意味着在未来的版本中这个问题将得到解决。