1

我定义了两个对象:

  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. 错误跟踪器上的问题在这里
4

1 回答 1

1

(对于箭头版本 0.9.1-SNAPSHOT 和之前的版本)

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

简短的总结是,每当您尝试实现类型类时,编译器都需要您的数据类型的 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 上尝试其他选项。意味着在未来的版本中这个问题将得到解决。

于 2019-06-16T11:48:32.443 回答