与标识映射并应用副作用的模式
Pattern for mapping with identity and applying a side-effect
是否有更清晰的方式表达以下模式:
def getUser(id: String): Option[User] = ???
getUser("12345").map { user =>
someSideEffect(user)
user
}
注意给定一个仿函数,我们如何使用恒等函数进行映射,同时也将副作用函数应用于盒装值。
Future.andThen
正是这样做的:
Applies the side-effecting function to the result of this future, and
returns a new future with the result of this future.
是否有类似 Future.andThen
但在一般情况下适用于任何函子的东西?
没有开箱即用的东西。人们经常用这样的东西来添加它:
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)
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)
Scala 2.13 开箱即用 tap
import scala.util.chaining._
Some(42) tap println
cats companion mouse
有它作为 <|
import mouse.all._
Some(42) <| println
两者都输出
Some(42)
res1: Some[Int] = Some(42)
在 cats 回购 Kestrel combinator for Monad/Functor #1559 和 flatTap
而非 tap
的规定中存在关于此主题的已解决问题。
是否有更清晰的方式表达以下模式:
def getUser(id: String): Option[User] = ???
getUser("12345").map { user =>
someSideEffect(user)
user
}
注意给定一个仿函数,我们如何使用恒等函数进行映射,同时也将副作用函数应用于盒装值。
Future.andThen
正是这样做的:
Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.
是否有类似 Future.andThen
但在一般情况下适用于任何函子的东西?
没有开箱即用的东西。人们经常用这样的东西来添加它:
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)
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)
Scala 2.13 开箱即用 tap
import scala.util.chaining._
Some(42) tap println
cats companion mouse
有它作为 <|
import mouse.all._
Some(42) <| println
两者都输出
Some(42)
res1: Some[Int] = Some(42)
在 cats 回购 Kestrel combinator for Monad/Functor #1559 和 flatTap
而非 tap
的规定中存在关于此主题的已解决问题。