首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Bind.ap是由Bind.bind在Scalaz 7中实现的

为什么Bind.ap是由Bind.bind在Scalaz 7中实现的
EN

Stack Overflow用户
提问于 2013-08-23 05:58:22
回答 2查看 106关注 0票数 0

我正在学习Scalaz 7,类型类系统是如此抽象,我无法理解的一件事是,为什么Bind.ap是由bind以这样的方式实现的。

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


trait Bind[F[_]] extends Apply[F] { self =>
  /** Equivalent to `join(map(fa)(f))`. */
  def bind[A, B](fa: F[A])(f: A => F[B]): F[B]

  override def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B] = bind(f)(f => map(fa)(f))
  ....
}

我知道我们可以把F[A => B]看作F[C],所以bind的第一个参数是有意义的,但是第二个参数需要A => F[B]f => map(fa)(f)如何等同于A => F[B] ??

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-23 07:18:11

我知道我们可以把F[A => B]当成F[C]

所以CA => B。让我们称之为事实1。

让我们重写bind,用C替换A,用D替换B,这样就不会因为碰撞类型的参数变量而混淆了:

代码语言:javascript
复制
def bind[C, D](fc: F[C])(f: C => F[D]): F[D]

因此,第二个参数列表中的f参数必须是C => F[D]类型,可以编写(A => B) => F[D] (使用事实1)。注意,在bind(f)(f => ...)中,第二个f只是一个lambda参数(碰巧是一个函数),而第一个f不是一个函数。它可能是bind(f)(fun => map(fa)(fun))写的。

f => map(fa)(f)如何等同于A => F[B]??

嗯,这不是..。f => map(fa)(f)必须输入为(A => B) => F[D]。所以

  • fA => B型的
  • fa的类型是F[A],即ap的第一个参数列表中的fa,而不是绑定。
  • 地图的定义来看,map(fa)(f)将是F[B]类型

这意味着

代码语言:javascript
复制
 (A => B) =>   F[D]
    f     =>  map(fa)(f)
 (A => B) =>   F[B]
 // D is really B

所以bind(f)(f => map(fa)(f))F[B]型的,这是ap所需要的。

也许这使我们在概念上更加清楚,这就是正在发生的事情:

代码语言:javascript
复制
def ap[A, B](m_elem: => F[A])(m_fun: => F[A => B]): F[B] =
  for {
    fun <- m_fun
    elem <- m_elem
  } yield {
    fun(elem)
  }
//To hammer it home, same as: m_fun.flatMap(fun => m_elem.map(elem => fun(elem)))
票数 3
EN

Stack Overflow用户

发布于 2013-08-23 06:16:15

bind方法签名中可以看出,这只是Haskell命名flatMap函数的一种自命不凡的方式。因此,Bind特性为Monad提供了必要的flatMap

如果我们采用List[Int => String]而不是F[A => B],可能更容易理解,所以bind从列表中获取每个函数,假设我们有以下列表:List((x: Int) => (x + 1).toString)作为f参数,List(1,2)作为fa参数,并将Int => String函数的f参数(List >函数)中的每个函数应用到fa参数(List >的Int的每个值)。

因此,上的答案是f => map(fa)(f)等价于A => FB,在这段代码中,A是来自f ListInt => String函数,当您从fa List映射一些值时,得到F[B],它的类型为< code >D28

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

https://stackoverflow.com/questions/18395766

复制
相关文章

相似问题

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