如何处理`Reader` monad 和`Try`?

2023-11-24

我正在读这篇关于使用 Reader monad 在 scala 中进行依赖注入.

原始示例运行良好,但我对返回类型做了一些更改UserRepository.get/find。它是User,但我把它改成了Try[User].

然后代码就无法编译,我尝试了很多次,但还是没有成功。

import scala.util.Try
import scalaz.Reader

case class User(email: String, supervisorId: Int, firstName: String, lastName: String)

trait UserRepository {
  def get(id: Int): Try[User]

  def find(username: String): Try[User]
}

trait Users {

  def getUser(id: Int) = Reader((userRepository: UserRepository) =>
    userRepository.get(id)
  )

  def findUser(username: String) = Reader((userRepository: UserRepository) =>
    userRepository.find(username)
  )
}

object UserInfo extends Users {

  def userEmail(id: Int) = {
    getUser(id) map (ut => ut.map(_.email))
  }

  def userInfo(username: String) =
    for {
      userTry <- findUser(username)
      user <- userTry     // !!!!!!!! compilation error
      bossTry <- getUser(user.supervisorId)
      boss <- bossTry     // !!!!!!!! compilation error
    } yield Map(
      "fullName" -> s"${user.firstName} ${user.lastName}",
      "email" -> s"${user.email}",
      "boss" -> s"${boss.firstName} ${boss.lastName}"
    )
}

编译错误是:

Error:(34, 12) type mismatch;
 found   : scala.util.Try[Nothing]
 required: scalaz.Kleisli[scalaz.Id.Id,?,?]
      user <- userTry
           ^

and

Error:(36, 12) type mismatch;
 found   : scala.util.Try[scala.collection.immutable.Map[String,String]]
 required: scalaz.Kleisli[scalaz.Id.Id,?,?]
      boss <- bossTry
           ^

我读过的文档Kleisli.flatMap(返回类型为findUser and getUser is Kleisli),要求参数类型为:

B => Kleisli[M, A, C]

Since a Try不会是一个Kleisli,有这样的错误。

我不知道如何处理。我可以用吗scala.util.Try这里?我怎样才能把它变成KLeisli类型?我怎样才能使这个例子发挥作用?


您可以使用ReaderTMonad 变压器来组成Reader单子和Trymonad 成一个单一的 monad,你可以使用for- 理解等

ReaderT只是一个类型别名Kleisli,你可以使用Kleisli.kleisli代替Reader.apply构建你的Reader-y 计算。请注意,您需要scalaz-contrib对于 monad 实例Try(或者您可以自己编写 - 这非常简单)。

import scala.util.Try
import scalaz._, Scalaz._
import scalaz.contrib.std.utilTry._

case class User(
  email: String,
  supervisorId: Int,
  firstName: String,
  lastName: String
)

trait UserRepository {
  def get(id: Int): Try[User]

  def find(username: String): Try[User]
}

trait Users {
  def getUser(id: Int): ReaderT[Try, UserRepository, User] =
    Kleisli.kleisli(_.get(id))

  def findUser(username: String): ReaderT[Try, UserRepository, User] =
    Kleisli.kleisli(_.find(username))
}

既然已经完成了,UserInfo更简单(而且现在也可以编译!):

object UserInfo extends Users {
  def userEmail(id: Int) = getUser(id).map(_.email)

  def userInfo(
    username: String
  ): ReaderT[Try, UserRepository, Map[String, String]] =
    for {
      user <- findUser(username)
      boss <- getUser(user.supervisorId)
    } yield Map(
      "fullName" -> s"${user.firstName} ${user.lastName}",
      "email" -> s"${user.email}",
      "boss" -> s"${boss.firstName} ${boss.lastName}"
    )
}

我们可以展示它的工作原理:

import scala.util.{ Failure, Success }

val repo = new UserRepository {
  val bar = User("[email protected]", 0, "Bar", "McFoo")
  val foo = User("[email protected]", 0, "Foo", "McBar")

  def get(id: Int) = id match {
    case 0 => Success(bar)
    case 1 => Success(foo)
    case i => Failure(new Exception(s"No user with id $i"))
  }

  def find(username: String) = username match {
    case "bar" => Success(bar)
    case "foo" => Success(foo)
    case other => Failure(new Exception(s"No user with name $other"))
  }
}

进而:

UserInfo.userInfo("foo").run(repo).foreach(println)
Map(fullName -> Foo McBar, email -> [email protected], boss -> Bar McFoo)

与您运行的方式完全相同Reader,但是你会得到一个Try在最后。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理`Reader` monad 和`Try`? 的相关文章

  • 手动排除sbt中的一些测试类

    我通常在 CI 中执行以下命令 清理更新编译测试发布 但是 我想从 sbt 命令行中排除 1 个 或几个 测试类 我怎样才能做到这一点 我不想更改我的代码以使用忽略等 两种可能的选择 test only See http www scala
  • Scala Sparkcollect_list() 与 array()

    有什么区别collect list and array 在 Spark 中使用 scala 我看到到处都有使用情况 但我不清楚用例来确定差异 尽管两者array https spark apache org docs latest api
  • 如何在cassandra中保存spark流数据

    构建 sbt以下是build sbt文件中包含的内容 val sparkVersion 1 6 3 scalaVersion 2 10 5 resolvers Spark Packages Repo at https dl bintray
  • Scala 警告、IntelliJ 和编译器标志

    我目前正在试用 IntelliJ Scala 插件 有件事让我有点烦恼 编译时我收到 3 个警告 Warning scala Recompiling 4 files Warning scala Warning scala there wer
  • Scala REPL / SBT Console 是否有配置文件?

    我一直在尝试找到某种点文件来放入 Scala REPL 设置和自定义函数 我特别有兴趣传递它的标志 例如 Dscala color 启用语法突出显示 以及覆盖设置 如结果字符串截断 scala gt power scala gt vals
  • 在 Spark 中将多行汇总为单行和单列

    我有一个如下的火花 DF 我需要汇总具有与单行相同 ID 的多行 但值应该不同 id values 1 hello 1 hello Sam 1 hello Tom 2 hello 2 hello Tom 预期输出 id values 1 h
  • 理解 scala 的 _ 与 Any/Nothing

    如果一个类具有协变类型参数 例如Iterable A http www scala lang org archives downloads distrib files nightly docs 2 10 1 library index ht
  • Java EE7 中 Qualifier 中的 @Nonbinding 注释的目的是什么?

    我正在阅读CDIJavaEE 7 中的注入特别是使用 Qualifier and Produces注入一个custom Data type变成一颗豆子 我有以下代码取自JBoss 文档 http docs jboss org weld re
  • Build.scala中%和%%符号含义

    我是新来玩的 Framework 2 1 java版本 并且没有scala经验 我不明白什么是以及什么是 and 在 Build scala 中表示 我用谷歌搜索了它们但找不到它们的含义 在我的 Build scala 文件中 我有 org
  • Scalaz 拆箱标记类型不会自动拆箱

    Reading http eed3si9n com learning scalaz Tagged type html http eed3si9n com learning scalaz Tagged type html并尝试示例代码 imp
  • 将当前类作为 scala 中的参数传递

    如何传递当前类作为参数 在java中我们这样做 mymethod this class or mymethod MyClass class 如何将 scala 当前类传递给此方法 this getClass or classOf MyCla
  • Scala 匿名函数中的 return 语句

    为什么显式 return 语句 使用return关键字 在匿名函数中从封闭的命名函数返回 而不仅仅是从匿名函数本身返回 例如 以下程序会导致类型错误 def foo String x Integer gt return x foo 我知道建
  • 对 Spark 数据集中的数字字符串进行排序

    假设我有以下内容Dataset productCode amount XX 13 300 XX 1 250 XX 2 410 XX 9 50 XX 10 35 XX 100 870 Where productCode is of Strin
  • 读取不同文件夹深度的多个 csv 文件

    我想递归地将给定文件夹中的所有 csv 文件读入 Spark SQLDataFrame如果可能的话 使用单一路径 我的文件夹结构如下所示 我想包含具有一个路径的所有文件 resources first csv resources subfo
  • 如何使用精炼库定义 A 和 B 取决于彼此的类型类?

    Problem 我有一个案例类 Passenger 从 A 点出发 前往 B 点 有效乘客意味着A点不等于B点 Passenger a Int b Int 问题 我如何使用设计乘客舱refind https index scala lang
  • 比较 javascript 元素和 scala 变量的 Play 框架 Twirl 模板

    如下面的代码示例所示 我想比较 scala 辅助元素内的 javascript 元素 然而 即使存在元素 abcde 它也始终返回 false 除了使用标签之外 如何获取 scala 辅助元素内的 javascript 值 appSeq S
  • Scala 中用于阻止调用的 Future

    The Akka文档说 you may be tempted to just wrap the blocking call inside a Future and work with that instead but this strate
  • 在 Scala 中反转地图的优雅方法

    目前正在学习Scala 需要反转Map 来进行一些反转值 gt 键查找 我一直在寻找一种简单的方法来做到这一点 但只想到了 Map origMap map kvp gt kvp 2 gt kvp 1 有人有更优雅的方法吗 假设值是唯一的 则
  • Spark scala:大量列上的简单 UDF 会导致性能下降

    我有一个包含 1 亿行和约 10 000 列的数据框 这些列有两种类型 标准 C i 和动态 X i 这个dataframe是经过一些处理后得到的 性能很快 现在只剩下2步了 Goal 需要使用 C i 列的相同子集对每个 X i 执行特定
  • 与文件名中的冒号“:”作斗争

    我有以下代码 用于加载大量 csv gz 并将它们转储到其他文件夹中 并将源文件名作为一列 object DailyMerger extends App def allFiles path File List File val parts

随机推荐

  • Redis 是单线程的。那我为什么要用生菜呢?

    Redis 4 0之后 Redis可以多线程执行一些功能 1 删除后台对象等 但Redis通常仍然使用单线程 常见问题解答 Redis 所以我觉得生菜没什么用 Lettuce 是 Redis 客户端 可以在 1 个连接中使用多个线程 但 R
  • 如何确保提交到 ThreadPoolExecutor 然后取消的 FutureTask 的垃圾回收?

    我正在提交Callable对象到ThreadPoolExecutor他们似乎一直留在记忆中 使用 Eclipse 的 MAT 工具查看堆转储 可以看到Callable对象正在被引用FutureTask Sync s callable多变的
  • eclipse中“JUnit插件测试”和“JUnit测试”之间的区别

    在eclipse运行命令中 有两种选择 JUnit Plug in Test and JUnit Test 之前 我尝试启动 eclipse 插件测试 org eclipse jdt ui tests refactoring 我遇到了一些问
  • 如何使用 C++ 在 Windows 中复制和粘贴文件?

    我已经用谷歌搜索过这个 但我仍然对如何使用它感到困惑 我正在制作一个文件管理器 我希望能够将文件复制并粘贴到新目录中 我知道要复制我需要使用file copy 但我不确定如何将其实现到我的代码中 我想使用 fstream 来做到这一点 如果
  • 缓存生成器

    最近的一个类似问题 isinstance foo types GeneratorType 还是inspect isgenerator foo 让我好奇如何一般地实现这一点 实际上 拥有一个生成器类型的对象似乎是一个普遍有用的东西 它将在第一
  • D3树:用线代替对角线投影

    我正在使用 d3 js 创建一棵树这个例子 这可以完美地处理我拥有的数据并产生期望的结果 除了一个细节 我不想要那些wiggly节点之间的连接线 我想要一条干净简单的线 谁能告诉我如何制作它 我一直在查看 d3 js 的 API 文档 但没
  • WPF WebBrowser 浏览器版本

    WPF WebBrowser 控件是否取决于用户计算机上安装的 IE 版本 或者它是否使用跨计算机一致的单独库 我读到它只能在 IE7 模式下呈现 但我想确保没有安装 IE 或由于某种原因仍在 IE6 上的用户不会出现任何问题 The MS
  • 点击 MKAnnotation 来“选择”它真的很慢

    在点击 MKMapView 上的注释和显示标注之间有近 0 5 秒的延迟 有谁知道为什么会出现这种情况 以及当用户点击地图时如何使其立即响应 即使用户位置注释在点击时在标注中显示 当前位置 也会发生这种情况 我希望它在点击时立即显示 没有奇
  • 找到重叠的圆圈

    我有一个矩形区域 其中有半径相等的圆 我想找到哪些圆与其他圆重叠 输出是重叠圆的 2 元素集的列表 我知道如何检查两个圆是否重叠 它们的中心之间的距离小于直径 我可以对每对圆圈执行此检查 但我想知道是否有更好的算法 比O n 2 EDIT
  • 用于 iOS 开发的 Objective-C++

    是否可以使用 Objective C 进行 iOS 应用程序 iPhone iPad iPod touch 开发 网上有例子和源代码吗 使用 ObjC 非常简单 您必须声明扩展名为 mm 的源文件 它将使编译器将它们视为 ObjC 与标头相
  • 在Eclipse中用subversion填充@version标签

    我想在 Eclipse 中使用 Subclipse 或 Subversion 填充注释标签 version CVS 会自动完成此操作 但 Subversion 不会 这会很有帮助 我尝试用谷歌搜索 version 但似乎不可能 CVS 所做
  • Puppeteer:如何单击元素以便在新选项卡中打开?

    我有一个包含 25 个可点击元素的列表 我需要在新选项卡中打开它们中的每一个 抓取在新选项卡中打开的新页面 然后将其关闭 然后转到下一个元素 并对列表中的每个元素执行相同的操作 但是 我在通过单击链接在新选项卡中打开链接时遇到问题 然后我设
  • 验证 mongoose 中父级范围内嵌入文档的唯一性

    我在猫鼬中有以下架构 UserSchema new Schema username type String required true GameSchema new Schema identifier String users UserSc
  • 是否可以防止从网站下载视频

    是否可以防止网站上的视频被下载 虽然用户可以使用某些硬件设备录制视频 但不可能使用某些链接下载视频 就像谷歌视频一样 例如 如果我的系统中有 Real One Player 我可以选择下载视频 这应该受到限制 是的 永远不要向任何人展示它
  • 核心数据实体继承 --> 限制?

    我想我会把这个发布到社区 我正在使用 coredata 并且有两个实体 两个实体都具有层级关系 我现在注意到有很多重复的功能 并且想知道是否应该重新构建一个抽象的基本实体 HierarchicalObject 并让我的实体继承它们 所以问题
  • JavaScript 中的三元运算符具有多个表达式?

    the styles the styles appendTo head the styles null the styles stylesheet detach 显然 这是无效的 注意 在 之间appendTo and the styles
  • python:获取长度为N的空格字符串的最简单方法

    在Python中生成长度为N的空格字符串的最简单方法是什么 除了像这样的东西 它是多行的 并且对于大 n 来说可能效率低下 def spaces n s for i in range n s return s 试试这个 简单 只有一行 n
  • 对角线使用 putText() ?使用 OpenCV

    是否可以使用 putText 方法在图片上对角线绘制文本 如果没有 除了使用 addWeighted 将两张图片混合在一起 其中一张是对角放置的文本 之外 还有其他选择吗 我正在尝试在图片上放置文本水印 我的问题是现在我正在使用 addWe
  • 理解 jq JOIN()

    我试图理解JOIN 内置于jq 来自 jq 手册 https stedolan github io jq manual JOIN idx stream idx expr join expr This builtin joins the va
  • 如何处理`Reader` monad 和`Try`?

    我正在读这篇关于使用 Reader monad 在 scala 中进行依赖注入 原始示例运行良好 但我对返回类型做了一些更改UserRepository get find 它是User 但我把它改成了Try User 然后代码就无法编译 我