我经常发现自己想要以更具功能性的方式将副作用函数链接到另一个方法调用的结尾,但我不想将原始类型转换为Unit
。假设我有一个read
方法在数据库中搜索记录,返回Option[Record]
。
def read(id: Long): Option[Record] = ...
如果read
返回Some(record)
,那么我可能想要缓存该值并继续前进。我可以这样做:
read(id).map { record =>
// Cache the record
record
}
但是,我想避免上面的代码并最终得到更像这样的东西,以便更清楚地了解发生了什么:
read(id).withSideEffect { record =>
// Cache the record
}
withSideEffect
返回与read(id)
相同的值。在搜索高低之后,我找不到任何类型的方法。我能想出的最接近的解决方案是使用隐式魔术:
implicit class ExtendedOption[A](underlying: Option[A]) {
def withSideEffect(op: A => Unit): Option[A] = {
underlying.foreach(op)
underlying
}
}
有没有Scala类型我可能会忽略这样的方法?使用这种方法是否存在任何潜在的设计缺陷?
答案 0 :(得分:1)
答案 1 :(得分:0)
您可以将scalaz用于副作用函数的“显式注释”。在scalaz 7.0.6中,它是IO monad:http://eed3si9n.com/learning-scalaz/IO+Monad.html
它在scalaz 7.1中已被弃用。我会用Task
做类似的事情val readAndCache = Task.delay(read(id)).map(record => cacheRecord(record); record)
readAndCache.run // Run task for it's side effects