我正在尝试编写F-代数,就像this page中那样。不同之处在于,与使用元组组合不同,如下所示:
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]] = ???有可能吗?我需要什么?或者使用无形状的HList会有帮助吗?
发布于 2018-01-25 19:41:53
如果我可以对您的约束做一些细微的修改,我就可以找到一个实现:
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]实例。但是从cats 2.3.0开始,添加了immutable.Seq的实例(这是Scala2.13中的默认scala.Seq )。
发布于 2018-01-25 20:10:24
完全同意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)https://stackoverflow.com/questions/48441062
复制相似问题