首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解FoldLeft在ScalaZ中的应用

理解FoldLeft在ScalaZ中的应用
EN

Stack Overflow用户
提问于 2017-11-16 18:48:46
回答 1查看 117关注 0票数 1

我正在阅读一些关于ScalaZ的文章,并有一个关于理解它的问题。在这个http://eed3si9n.com/learning-scalaz/sum+function.html中,我们推广和函数,抽象出要求和的类型。

代码语言:javascript
复制
def sum[T](xs: List[T])(implicit m: Monoid[T]) = //...

哪里

特质MonoidA的定义如下:

代码语言:javascript
复制
trait Monoid[A] {
  def mappend(a1: A, a2: A): A
  def mzero: A
}

是的,这很清楚。这里的Monoid对应于代数一元结构。现在,在这个http://eed3si9n.com/learning-scalaz/FoldLeft.html中,它对列表进行抽象。为此,我们定义了以下特性:

代码语言:javascript
复制
trait FoldLeft[F[_]] {
  def foldLeft[A, B](xs: F[A], b: B, f: (B, A) => B): B
}
object FoldLeft {
  implicit val FoldLeftList: FoldLeft[List] = new FoldLeft[List] {
    def foldLeft[A, B](xs: List[A], b: B, f: (B, A) => B) = xs.foldLeft(b)(f)
  }
}

因此,现在我们可以定义和函数如下:

代码语言:javascript
复制
def sum[M[_]: FoldLeft, A: Monoid](xs: M[A]): A = {
  val m = implicitly[Monoid[A]]
  val fl = implicitly[FoldLeft[M]]
  fl.foldLeft(xs, m.mzero, m.mappend)
}

我不是理论范畴专家,但在我看来,它就像应用函子。对吗?我们能提供这类理论的相似性吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-16 20:05:48

应用函子是一个类型类,有两个操作:A => F[A]F[A => B] => F[A] => F[B]。你提到的所有操作都没有这样的签名。FoldLeft更像是折叠式。它是一个不同类型的类,是可穿 (又名Traverse)的父类。TraversableApplicative连接。

代码语言:javascript
复制
trait Functor[F[_]] {
  def fmap[A, B](f: A => B)(fa: F[A]): F[B]
}

trait Applicative[F[_]] extends Functor[F] {
  def pure[A](a: A): F[A]
  def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
  override def fmap[A, B](f: A => B)(fa: F[A]): F[B] = ap(pure(f))(fa)
}

trait Foldable[T[_]] {
  def foldr[A, B](op: A => B => B)(seed: B)(ta: T[A]): B =
    (foldMap(op)(ta) _)(seed)
  def foldMap[A, M](f: A => M)(ta: T[A])(implicit monoid: Monoid[M]): M =
    foldr[A, M](a => m => monoid.append(f(a), m))(monoid.empty)(ta)
}

trait Traversable[T[_]] extends Functor[T] with Foldable[T] {
  def traverse[F[_]: Applicative, A, B](k: A => F[B])(ta: T[A]): F[T[B]] = 
    sequence[F, B](fmap[A, F[B]](k)(ta))
  def sequence[F[_]: Applicative, A](tfa: T[F[A]]): F[T[A]] = 
    traverse[F, F[A], A](fa => fa)(tfa)
  override def fmap[A, B](f: A => B)(ta: T[A]): T[B] = traverse[Id, A, B](f)(ta)
  override def foldr[A, B](op: A => B => B)(seed: B)(ta: T[A]): B =
    (traverse[Const[B => B]#λ, A, B](op)(ta) _)(seed)
  override def foldMap[A, M: Monoid](f: A => M)(ta: T[A]): M =
    traverse[Const[M]#λ, A, M](f)(ta)
}

type Id[A] = A

trait Const[C] {
  type λ[A] = C
}

类型类Functor意味着您有一个“容器”F[_],并且您知道如何在这个容器中应用函数f: A => B。类型类Applicative意味着您知道如何将值a: A打包到这个容器中,以及如何将“函数”F[A => B]应用于“值”F[A]Foldable意味着您知道如何使用二进制操作A => B => B和起始值B以及接收结果B折叠容器。Traversable意味着您知道如何遍历容器,在每个“节点”中执行应用程序效果A => F[B]

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47337057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档