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

时间:2019-04-21 21:23:56

标签: gradle kotlin kapt arrow-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的同一文件中,那么我就可以看到该仿函数的生成代码。
  3. li>

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

已更新

这是我的代码到存储库的链接:repository

1 个答案:

答案 0 :(得分:1)

(用于0.9.1-SNAPSHOT及更低版本的箭头版本)

Higherkinded处理器和扩展处理器具有依赖性。正确地,扩展注释取决于更高种类的注释生成的代码。为什么要检查此link

简短的摘要是,每当您尝试实现类型类时,编译器都需要数据类型的Higherkinded Types。

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