如何阅读这个flatMap代码? [英] How to read this flatMap code?

查看:159
本文介绍了如何阅读这个flatMap代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法破译以下功能。特别是flatMap线 - 'aa'和'bb'在哪里?来自变量,以及如何执行?也许如果有人能够用语言解释这段代码会发生什么,这将会有所帮助。

  def map2 [EE>:E,B,C]( b:(EE,B))(f:(A,B)=> C):[EE,C] = 
这个flatMap(aa => b map(bb => f aa,bb)))

以下是flatMap函数:
$ (EE,B]):或者[EE,B] =这个匹配项[b,b,c] {
case Right(r)=> f(r)
case Left(e)=>左(e)
}

和地图:

pre $ def $ map $ B $($)$($)$($) >右(f(r))
情况左(e)=>左(e)
}


解决方案

所有这些功能都是为任一类定义的。或者可以处于两个状态 - 右侧 - 正确的值和Left,它解释了屁股错误。



让我们从地图定义开始。我们使用类型A参数化了。 map 接受将类型A转换为B的函数。因此,map函数检查值是否为Right,然后将给定的函数f应用于Right值,并用Right包装并返回。

  Right [String,Int](4).map(_ * 3)//给出错误Right(12)
Left [String,Int](error)。map(_ * 3)//给出Left(error)

flatMap 类似于map,但接受函数转换类型A到右边类型B,所以不像map我们不需要包装右值[b]

 右[String,Int](5).flatMap(item => Right(item * 3))/ / given Right(15)
Left [String,Int](error)。flatMap(item => Right(item * 3))//给出Left(error)

根据定义, map2 采用Either b和function的实例,将类型A和B到第三个值C,并返回用Either包装的结果。让我们仔细看看它是如何实现的。

  this.flatMap(aa => b map(bb => f (aa,bb)))

让我们用flatMap的定义重写它:

  this.match {
case Right(r)=> b.map(bb => f(r,bb))
case Left(e)=>左(e)
}

并应用地图:

  this.match {
case Right(r)=> {
b match {
case Right(br)=>右(f(r,br))
case左(be)=>左(be)
}
}
左(e)=>左(e)
}

所以有三条路径:

 如果正确的a和正确的b然后应用函数(a,b)
如果正确a和错误b然后错误(b)
如果出现错误,则出现错误a

示例:

  Right(7).map2(Right(4)){case(a,b)=> a * b} //给出Right(28)
Right(7).map2(Left [String,Int](failed)){case(a,b)=> (a,b)给出Left(failed)
Left [String,Int](error)。map2(Left [String,Int](failed)){case(a,b) => a * b} //给出Left(error)

编辑:内部函数解释



您必须传递给flatMap函数,类型为:

  A => ;无论是[EE,C] 

这意味着采用A类型的参数并将其转换为请键入[EE,C]



,以便您可以定义:

 <$ c $ (EE,B))(f:(A,B)=> C):[EE,C] = {
bf func(aa:A):或者[EE,C] = {
b map(bb => f(aa,bb))
}
这个flatMap(func)
}


I'm having trouble deciphering the following function. Particularly, the flatMap line - where are the 'aa' and 'bb; variables coming from, and how is this executed? Maybe if someone could explain in words what is happening with this code it would be helpful. I'm just really struggling how to read this syntax.

def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = 
    this flatMap(aa => b map (bb => f(aa, bb)))

Here is the flatMap function:

 def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match {
   case Right(r) => f(r)
   case Left(e) => Left(e)
 }

and map:

def map[B](f: A => B): Either[E, B] = this match {
   case Right(r) => Right(f(r))
   case Left(e) => Left(e)
 }

解决方案

Looks like all these functions are defined for Either class. Either can be in two 'states' - Right - correct value and Left which interpreted ass error.

Lets go from the map definition. We have Either parametrized with type A. map accepts function converting type A to B. So map function checks if value is Right then it applies given function f to Right value, wraps it with Right and return. If error then just return error.

Right[String, Int](4).map(_*3)      // gives Right(12)
Left[String, Int]("error").map(_*3) // gives Left("error")

flatMap is similar to map, but accepts function converting type A to Either of right type B, so unlike map we don't need to wrap right value

Right[String, Int](5).flatMap(item => Right(item*3))        //gives Right(15)
Left[String, Int]("error").flatMap(item => Right(item*3))   //gives Left("error")

As defined, map2 takes instance of Either b and function, converting pair of values of types A and B to some third value C, and return the result wrapped with Either. Let's take closer look at how it is implemented.

this.flatMap(aa => b map (bb => f(aa, bb)))       

lets rewrite it with definition of flatMap:

this.match {
  case Right(r) => b.map (bb => f(r, bb))
  case Left(e) => Left(e)
}

And apply map:

this.match {
  case Right(r) => {
    b match {
      case Right(br) => Right(f(r, br))
      case Left(be) => Left(be)
    }
  }
  case Left(e) => Left(e)
}

So there are three paths:

if right a and right b then apply function(a,b)
if right a and error b then error(b)
if error a then error a

Examples:

Right(7).map2(Right(4)){case (a,b) => a*b} // gives Right(28)
Right(7).map2(Left[String, Int]("failed")){case (a,b) => a*b}  //gives Left("failed")
Left[String, Int]("error").map2(Left[String, Int]("failed")){case (a,b) => a*b}  //gives Left("error")

Edit: Inner function explanation

You have to pass to a flatMap function with type:

A => Either[EE, C]

It means "take an argument of type A and convert it to result of type Either[EE,C]"

so you could define:

def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {     
  def func(aa:A):Either[EE, C] = {
     b map (bb => f(aa, bb))
  }
  this flatMap(func)
}

这篇关于如何阅读这个flatMap代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆