pme*_*pme 6 monads functional-programming scala
我经常想记录或打印一些东西而不改变它。
它看起来像这样:
val result = myResult // this could be an Option or a Future
.map{r =>
info(s"the result is $r")
r
}
Run Code Online (Sandbox Code Playgroud)
这三行总是相同的。
在 for 理解中,这可以做得更好一些。
但我正在寻找第一个声明性版本的解决方案。它应该看起来像:
val result = myResult
.log(info(s"the result is ${_}"))
Run Code Online (Sandbox Code Playgroud)
这条单线可以放在链中可能有地图的每个位置,例如:
val result = myResult
.log(info(s"1. ${_}"))
.filter(_ > 1)
.log(info(s"2. ${_}"))
...
Run Code Online (Sandbox Code Playgroud)
如何才能实现这一目标?如果可能的话,没有函数库。
好吧,所以我决定对此采取行动,我想撤回我的评论
也许您可以定义一个隐式类,该类具有作用于 Product 的方法“log”?
我确信 Future 和所有 monad(集合、选项)拥有共同的祖先,但事实证明我错了。我有以下解决方案,不使用猫。除了前面提到的“ flatTap ”之外,这可以在猫身上以更漂亮的方式完成,并可能用 cats.Ref 或其他东西进行修饰。
Future 是这里明显的概述,但随着更多例外的出现,您可能需要扩展此对象。
import scala.concurrent._
import ExecutionContext.Implicits.global
object MonadicConv {
implicit class MonadicLog[+B <: Product, A] (val u: B){
def log(l: String, args: List[A] = List()): B = {
println("logging")
println(u)
println(l)
u
}
}
implicit class FutureLog[T, A](val u: Future[T]){
def log(l: String, args: List[A] = List()) : Future[T] = {
println("logging")
println(u)
println(l)
u
}
}
}
Run Code Online (Sandbox Code Playgroud)
1)你需要用你自己的日志逻辑修改它,我只是打印
2)我对此并不感到非常自豪,因为这不再是一个纯函数。我不确定 Scala 中是否可以在不使用 Cats 的情况下解决这个问题。(可能有)
3)参数可以删除,只需添加它们,以防您想传递额外信息
4)如果你真的想结合这些,你可以尝试定义你自己的产品,一些线索:Implement Product type in Scala with generic update function work on its parts
你可以使用它
import MonadicConv._
val x = Some(5).log("").get
val lx = List(Some(5), Some(10), Some(1)).log("list").flatten.log("x").filter(_ > 1).log("")
val ff = Future.successful(List(Some(5), Some(10), Some(1))).log("fff").map(_.flatten.filter(_ > 1).log("inner")).log("")
Run Code Online (Sandbox Code Playgroud)
这打印出来
logging
Some(5)
option test
logging
List(Some(5), Some(10), Some(1))
list test
logging
List(5, 10, 1)
flat test
logging
List(5, 10)
filter test
logging
Future(Success(List(Some(5), Some(10), Some(1))))
future test
logging
Future(<not completed>)
incomplete test
logging
List(5, 10)
inner future test
Run Code Online (Sandbox Code Playgroud)
斯卡斯蒂版本在这里
正如我所提到的,此时此刻这确实是猫的土地。这是我在 Scala 核心中能想到的最好的