scala - 如何定义在免费应用程序中使用的递归代数?

标签 scala scalaz applicative scala-cats

我面临着定义与 FreeApplicative 一起使用的递归代数的问题。

这是我失败的尝试。 假设我们希望该功能标记(组)有效值。 我已插入虚拟 Print 以获得一些构造函数。

sealed trait Algebra[F[_],T]
case class Print[F[_]](s: String) extends Algebra[F,String]
case class Prefix[F[_],T](p: String, tagged: F[T]) extends Algebra[F,T]

当我尝试通过(使用kind-projector)定义自由类型FA

type FA[T] = FreeApplicative[Algebra[FA,?],T]

然后编译器提示

Error:(28, 38) illegal cyclic reference involving type FA type FA[T] = FreeApplicative[Alg[FA,?], T]

如何解决这个问题?

我认为在使用Free(monads)时,Prefix 的签名可以省略对tagged 的引用。 当 monad 链接它们的代数调用时,人们可以简单地记住执行路径上的所有前缀调用。 但对于 Applicative,我不知道如何实现这一点。

最佳答案

您要求使用代数指令来引用本身使用代数构建的自由程序。

您需要定义自己的“递归”免费应用程序:

case class FreeApRec[F[_[_], _], A](fa: FreeApplicative[F[FreeApRec[F, ?], ?], A])

并实现您需要的方法(这只是转发到 FreeApplicative 的方法并包装结果)。

Here is the same done for the Free monad.


您也可以通过更高级的定点运算符定义上面的 FreeApRec 类型,但定义变得不太透明:

case class HFix[F[_[_], _], A](unfix: F[HFix[F, ?], A])

type FreeApRecF[F[_[_], _], K[_], A] = FreeApplicative[F[K, ?], A]

type FreeApRec[F[_[_], _], A] = HFix[FreeApRecF[F, ?[_], ?], A]

关于scala - 如何定义在免费应用程序中使用的递归代数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49509643/

相关文章:

scala - Spark SQL 仅映射一列 DataFrame

scala - 将 scalaz 析取集合转换为单个析取

javascript - 什么是我的应用仿函数不能与 Ramda 的 ap 一起工作?

scala - Scalaz 中 *> 和 <* 的用途是什么

haskell - 为什么 f <$> g <$> x 等价于 (f . g) <$> x 虽然 <$> 不是右结合的?

Scala 函数文字和方法以及下划线

scala - 为什么 "type class"称为 "type class"?

scala - 在 Scala 项目中使用 sbt 程序集时在 jar 中包含 Hyperic Sigar 库

scala - 无定型:通过镜盒类别或视场参数化的通用镜片

scala - flatMap 与 ValidationNel 的析取