将 F-Algebra[F, A] 组合成 F-Algebra[F, Seq[A]]
Composing F-Algebra[F, A] to F-Algebra[F, Seq[A]]
我正在尝试像 this page 中那样编写 F 代数。不同之处在于,不是用元组组合,而是像这样:
type FAlgebra[F[_], A] = F[A] => A
def algebraZip[F[_], A, B](fa: FAlgebra[F, A], fb: FAlgebra[F, B])
(implicit F: Functor[F]): FAlgebra[F, (A, B)] =
fab => {
val a = fa(fab.map(_._1))
val b = fb(fab.map(_._2))
(a, b)
}
我想使用 Seq
,像这样:
def algebraSeq[F[_], A](fa: FAlgebra[F, A])
(implicit F: Functor[F]): FAlgebra[F, Seq[A]] = ???
可能吗?我需要什么?或者使用 shapeless HList
会有帮助吗?
如果我可以对你的约束做一些细微的改动,我可以找到一个实现:
def algebraSeq[F[_]: Traverse, A](fa: FAlgebra[F, A]): FAlgebra[F, Seq[A]] =
fseq => fseq.sequence.map(f => fa(f))
我需要 Traverse
实例才能将 F[Seq[A]]
排序为 Seq[F[A]]
。
过去您必须为 List
而不是 Seq
编写此函数,因为没有 Applicative[Seq]
实例。但是由于添加了 immutable.Seq
的 cats 2.3.0 实例(这是 Scala 2.13 中的默认 scala.Seq
)。
完全同意Jasper的回答。但我喜欢概括 ;)
你的代数形状就像 CoKleisli:
import cats._
import cats.implicits._
import cats.data.Cokleisli
type FAlgebra[F[_], A] = Cokleisli[F, A, A]
def nestEffect[F[_], A, B, G[_]](coKleisli: Cokleisli[F, A, B])
(implicit F: Traverse[F], G: Applicative[G]): Cokleisli[F, G[A], G[B]] =
Cokleisli((fga: F[G[A]]) => F.sequence[G, A](fga).map(coKleisli.run))
def algebraSeq[F[_], A](fa: FAlgebra[F, A])
(implicit F: Traverse[F]): FAlgebra[F, List[A]] =
nestEffect[F, A, A, List](fa)
我正在尝试像 this page 中那样编写 F 代数。不同之处在于,不是用元组组合,而是像这样:
type FAlgebra[F[_], A] = F[A] => A
def algebraZip[F[_], A, B](fa: FAlgebra[F, A], fb: FAlgebra[F, B])
(implicit F: Functor[F]): FAlgebra[F, (A, B)] =
fab => {
val a = fa(fab.map(_._1))
val b = fb(fab.map(_._2))
(a, b)
}
我想使用 Seq
,像这样:
def algebraSeq[F[_], A](fa: FAlgebra[F, A])
(implicit F: Functor[F]): FAlgebra[F, Seq[A]] = ???
可能吗?我需要什么?或者使用 shapeless HList
会有帮助吗?
如果我可以对你的约束做一些细微的改动,我可以找到一个实现:
def algebraSeq[F[_]: Traverse, A](fa: FAlgebra[F, A]): FAlgebra[F, Seq[A]] =
fseq => fseq.sequence.map(f => fa(f))
我需要 Traverse
实例才能将 F[Seq[A]]
排序为 Seq[F[A]]
。
过去您必须为 List
而不是 Seq
编写此函数,因为没有 Applicative[Seq]
实例。但是由于添加了 immutable.Seq
的 cats 2.3.0 实例(这是 Scala 2.13 中的默认 scala.Seq
)。
完全同意Jasper的回答。但我喜欢概括 ;)
你的代数形状就像 CoKleisli:
import cats._
import cats.implicits._
import cats.data.Cokleisli
type FAlgebra[F[_], A] = Cokleisli[F, A, A]
def nestEffect[F[_], A, B, G[_]](coKleisli: Cokleisli[F, A, B])
(implicit F: Traverse[F], G: Applicative[G]): Cokleisli[F, G[A], G[B]] =
Cokleisli((fga: F[G[A]]) => F.sequence[G, A](fga).map(coKleisli.run))
def algebraSeq[F[_], A](fa: FAlgebra[F, A])
(implicit F: Traverse[F]): FAlgebra[F, List[A]] =
nestEffect[F, A, A, List](fa)