scala - Scala-cats,用 ReaderT 编写 Reader
问题描述
这是一个小的函数组合,所有这些函数都返回ReaderT
:
type FailFast[A] = Either[List[String], A]
def f1:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f2:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Left(List("d")))
def f3:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def f4:ReaderT[FailFast, Map[String,String], Boolean] = ReaderT(_ => Right(true))
def fc:ReaderT[FailFast, Map[String,String], Boolean] =
f1.flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
如何实现fc
以防万一f1
返回Reader
,但不是ReaderT
:
def f1:Reader[Map[String,String], Boolean] = Reader(_ => true)
现在我必须作曲,Reader
这正是ReaderT[Id, ...]
Reader[FailFast, ...]
解决方案
正如您提到Reader[A, B]
的那样ReaderT[Id, A, B]
(它本身只是 的类型别名Kleisli[Id, A, B]
)。
由于您使用的是猫,因此有一个方法称为mapK
映射 的第一个类型参数ReaderT
,您只需要提供一个FunctionK/~>
用于转换的实例。所以在你的情况下,它看起来像这样:
val Id2FailFast = new (Id ~> FailFast) {
def apply[T](f: Id[T]): FailFast[T] = Right(f)
}
f1.mapK(Id2FailFast).flatMap( b1 => {
if (b1)
for {
b2 <- f2
b3 <- f3
b4 <- f4
} yield b4
else ReaderT(_ => Right(true))
})
可能还有其他一些重构可以进一步清理它,比如使用 anEitherT
但是因为它看起来有点人为的例子,所以我将把它作为练习留给读者。
推荐阅读
- python - 用于拉丁 Python 的词性标注器
- python - Elasticsearch 查询日期范围不起作用
- c# - 在 C# 中从 Excel 中读取时间显示格式
- ruby-on-rails - 不能 :destroy 如果最后存在
- angular - 无法处理基于 Ubuntu 的弹出窗口以使用量角器浏览和上传图像
- c# - 在 NAudio 中使用断言
- javascript - 如何为一个元素设置更改属性?使用 JS 而不是 JQuery
- selenium - “org.openqa.selenium.WebDriverException:java.net.SocketException:软件导致连接中止:recv 失败”尝试启动 Firefox
- java - 流 - 过滤所有不抛出异常
- maven - 部署到 Heroku 时自定义 Maven 命令