当前位置: 首页 > 知识库问答 >
问题:

当返回类型为Option[Error]时处理快速失败失败

淳于嘉树
2023-03-14

我已经发布了很多关于Scala失败处理的问题,非常感谢大家的回答。

我理解我的选择,当处理要么和Scalaz或一个理解,我有另一个(最后一个?)问题:

当操作与外部非功能世界(如数据库)打交道时,如何执行快速失败的操作序列?

我是说我有这样的方法:

def insertItem(item: Item): Either[Error,Item]

感谢Ay和这些答案,我知道如何使用Ayth来做到这一点:在Scala中使用Ayth和Method参数验证链接方法调用,用于理解和monads

但是我的Itemcase类是不可变的,将其作为right返回并没有真正意义,因为调用者已经拥有该值。

因此,我怎样才能对以下各项做同样的事情:

def insertItem(item: Item): Option[Error]

在我的应用程序中,当创建一个用户时,我们也为他创建一些项目。如果一个项目创建失败,那么整个过程应该停止。

当我在a中直接使用选项[Error]进行理解时,我认为我不会得到预期的结果。

我想做这样的事情是有意义的:

for {
  _ <- insertItem(item1).toLeft("???").right
  _ <- insertItem(item2).toLeft("???").right
  _ <- insertItem(item3).toLeft("???").right
}

但正如价值观“???”我把我的权利从来没有用过,我想我错过了优雅的解决方案,它不涉及创建永远不会被使用的权利。

我想我在寻找一种只有当结果为<code>无

顺便说一句,如果可能的话,我想要非Scalaz和Scalaz解决方案。我不确定Scalaz是否能处理这些事情,因为它似乎更专注于真正的函数编程,并且可能没有为副作用行为提供代码,比如我的用例?

共有3个答案

百里俭
2023-03-14

如果要将包含 Option[Error] 的方法链接在一起,并且仅在“选项”为“无”时才执行下一步,则可以使用 orElse 来实现此目的。

柯乐童
2023-03-14

我们做了类似的事情,在那里我使用scalaz来快速失败消息发送,尽管这不是惯用的scalaz:

def insertItem(item: Item): Validation[Error, Unit]

val result = for {
  _ <- insertItem(item1)
  _ <- insertItem(item2)
  _ <- insertItem(item3)
} yield Unit
舒赞
2023-03-14

在这种情况下,我看不到不使用[Error, Unit]的原则性理由(或者至少我已经这样做了,我对此并不感到内疚)。假设我们有以下内容:

def launch(thing: String): Either[String, Unit] = Either.cond(
  thing.nonEmpty,
  println("Launching the " + thing),
  "Need something to launch!"
)

我们可以证明正确的投影monad是适当的惰性:

scala> for {
     |   _ <- launch("flowers").right
     |   _ <- launch("").right
     |   r <- launch("MISSILES").right
     | } yield r
Launching the flowers
res1: Either[String,Unit] = Left(Need something to launch!)

没有导弹被发射,如所愿。

值得注意的是,如果您使用Option而不是任一,则您描述的操作只是给定Option的“First”monud实例的总和(其中加法操作只是或Else)。例如,我们可以使用Scalaz 7编写以下内容:

import scalaz._, Scalaz._

def fst[A](x: Option[A]): Option[A] @@ Tags.First = Tag(x)

def launch(thing: String): Option[String] = if (thing.isEmpty) Some(
  "Need something to launch!"
) else {
  println("Launching the " + thing)
  None
}

现在:

scala> val r: Option[String] = fst(launch("flowers")) |+| fst(
     |   launch("")) |+| fst(launch("MISSILES"))
Launching the flowers
r: Option[String] = Some(Need something to launch!)

再一次,没有导弹。

 类似资料:
  • 本文向大家介绍svn 清理失败 (cleanup 失败) 的快速解决方法,包括了svn 清理失败 (cleanup 失败) 的快速解决方法的使用技巧和注意事项,需要的朋友参考一下 1、cmd指令,进入.svn目录,找到wc.db文件 sqlite 3 打开 2、 对 svn源代码目录 右键, clean up, 稍等1至5分钟左右,然后会提示 清理成功 以上就是小编为大家带来的svn 清理失败 (

  • 所以我尝试了kafka quickstart的主要文档。得到了多集群的例子,所有设置和测试的说明,它的工作。例如,扳倒一个代理,生产者和消费者仍然可以发送和接收。 经纪人1有什么特别的吗?查看配置,除了id、端口号和日志文件位置之外,所有3个代理之间的配置完全相同。 我认为这只是提供的控制台使用者没有接受代理列表的问题,所以我按照他们的文档使用默认设置编写了一个简单的java使用者,但是在“boo

  • 类项目: hbm文件: 方法如下:

  • 问题内容: 我试图在Windows 2008 R2中使用Kibana运行ElasticSearch。 我关注了这篇文章:在带有木瓜的Windows服务器上安装logstash 一步一步,但我得到的是: 当我去 我得到: 因此,似乎ElasticSearch正在运行,但是由于某些原因,Kibana无法连接到它。 ElasticSearch日志包含错误: 知道我在做什么错吗? 问题答案: 我也遇到过类

  • 本文向大家介绍浅谈golang类型断言,失败类型断言返回值问题,包括了浅谈golang类型断言,失败类型断言返回值问题的使用技巧和注意事项,需要的朋友参考一下 失败的类型断言,返回的值为最近断言类型的零值 代码入下: 补充:go语言interface{}类型断言的举例使用 在go语言里经常会用到interface{}类型,它是类似于c语言中的void *类型,可以接受任意类型的参数。当我们的函数或

  • 主要内容:1 ArrayList的概述,2 ArrayList的源码解析,2.1. 主要类属性,2.2 构造器与初始化容量,2.3 add方法与扩容机制,2.4 addAll方法,2.5 remove方法,2.6 get方法,2.7 set方法,2.8 clone方法,2.9 序列化,2.10. 其他方法,3 迭代器,3.1 Iterator迭代器,3.2 ListIterator列表迭代器,4 快速失败(fail-fast)与安全失败(fail-safe)机制,,,基于JDK1.8对Java中