用身份映射和应用副作用的模式

时间:2018-02-07 02:13:14

标签: scala

是否有更明确的方式来表达以下模式:

def getUser(id: String): Option[User] = ???

getUser("12345").map { user =>
  someSideEffect(user)
  user
}

注意给定一个仿函数我们如何使用身份函数进行映射,还将副作用函数应用于盒装值。

Future.andThen正是如此:

  

将副作用函数应用于此未来的结果,并且   这个未来的结果将带来一个新的未来。

是否有类似Future.andThen的内容,但在一般情况下适用于任何仿函数?

3 个答案:

答案 0 :(得分:5)

没有任何开箱即用的东西。人们通常会添加如下内容:

 object ImplicitUtils {
    implicit class Utils[T](val t: T) extends AnyVal {
       def tap(f: T => Unit): T = { f(t) ; t }
    }
 }

那么,现在你可以写:

 import ImplicitUtils._
 val user = getUser("foo").tap(someSideEffect)

答案 1 :(得分:2)

object FunctorAndThen {

  import cats.Functor
  import cats.implicits._
  import scala.language.higherKinds

  implicit class AndThen[F[_], A](val f: F[A])(implicit ev: Functor[F]) {
    def andThen(sideEffect: A => Unit): F[A] = {
      f.map(sideEffect)
      f
    }
  }
}

// Usage:

import FunctorAndThen._
import cats.implicits._

val result: Option[String] = Option("a").andThen(a => println(a))
println(result)

答案 2 :(得分:1)

Scala 2.13以tap

的形式提供
import scala.util.chaining._
Some(42) tap println

猫同伴mouse的名字为<|

import mouse.all._
Some(42) <| println

两者都输出

Some(42)
res1: Some[Int] = Some(42)

cats仓库Kestrel combinator for Monad/Functor #1559和提供flatTap而不是tap中对此主题有一个封闭的问题。