组合两个def后展平类型

维卡斯·潘迪亚(Vikas Pandya)

以下是一个玩具示例,以演示现实生活中的传统方法的形状怪异度和问题要点。

如您所见anotherFunc,映射后的personList扩展类型\/[Throwable,List[\/[Throwable,String]]]不是预期的返回类型,而是maping的作用personList再次在下面显示的内容anotherFunc是出于演示目的(实际上,发生了更多有意义的事情,而不是其中的Option("fakeString")任何事情

需求是map personList,如果需要,right则对List[Person]返回的每个元素right(从析取函数返回的那一侧)执行某些操作

如何简化/展平返回的类型anotherFunc(以return \/[Throwable,List[String]])。可能正在使用其他组合器?

case class Person(name :String)

def personList : \/[Throwable,List[Person]] ={
  \/.fromTryCatch{
    List(Person("John"))
  }
} 

def anotherFunc  : \/[Throwable,List[\/[Throwable,String]]]= {
  personList.map{ pl =>
    pl.map{p =>
      for{
        s <- Option("fakeString").\/>(new Throwable("not found"))
      } yield s

    }

  }
}
特拉维斯·布朗(Travis Brown)

诺亚的回答基本上是正确的,但您应始终使用traverse而不是map后跟一个sequence-两者是等效的,但前者更清晰,效率更高:

def anotherFunc: Throwable \/ List[String] = personList.flatMap { pl =>
  pl.traverseU { p =>
    for {
      // I assume you're doing something more interesting here...
      s <- Option("fakeString").\/>(new Throwable("not found"))
    } yield s
  }
}

不过,我将其作为答案而不是评论,因为还有另一种解决这类问题的方法,在某些情况下这种解决方案可能更优雅。如果您要处理大量的析取列表,则可以使用ListTmonad转换器使它看起来像在处理单个级别:

type OrThrowable[A] = Throwable \/ A    

def personList = ListT[OrThrowable, Person](
  \/.fromTryCatch { List(Person("John")) }
)

def anotherFunc: ListT[OrThrowable, String] = personList.flatMap { p =>
  Option("fakeString").\/>(new Throwable("not found")).liftM[ListT]
}

现在只需anotherFunc.run在末尾使用即可得到一个Throwable \/ List[Person],它与您当前的代码完全等效(但更加简洁)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章