加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何使用在内部进行理解?

发布时间:2020-12-16 09:56:11 所属栏目:安全 来源:网络整理
导读:我有这样的理解: for { (value1: String,value2: String,value3: String) - getConfigs(args) // more stuff using those values} getConfigs返回一个[Throwable,(Seq [String],String,String)],当我尝试编译时,我得到这个错误: value withFilter is not a
我有这样的理解:

for {
      (value1: String,value2: String,value3: String) <- getConfigs(args)
      // more stuff using those values
}

getConfigs返回一个[Throwable,(Seq [String],String,String)],当我尝试编译时,我得到这个错误:

value withFilter is not a member of Either[Throwable,(Seq[String],String)]

如何在for comprehension中使用此方法(返回Either)?

解决方法

像这样:

for {
   tuple <- getConfigs()
} println(tuple)

开玩笑说,我认为这是一个有趣的问题,但它有点错误.
问题(见上文)不是因为理解是不可能的,但在Either中不可能在for comprehension中进行模式匹配.

有documentation how for comprehensions are translated但不包括每个案例.据我所知,这个不在那里.所以我在我的“Scala编程” – 第二版(因为那是我在死树上的那个)的实例中查找了它.

第23.4节 – for表达式的翻译

如上所述,有一个子章节“在生成器中翻译模式”,这就是问题所在.它列出了两种情况:

案例一:元组

完全是我们的情况:

for ((x1,…,xn) <- expr1) yield expr2

应转换为expr1.map {case(x1,xn)=>表达式2).
这正是IntelliJ所做的,当您选择代码并执行“Desugar for comprehension”操作时.好极了!
……但是这让我的眼睛更加怪异,因为这些令人费解的代码实际上没有问题.

所以这个案例是(imho)匹配案例,但不是正在发生的事情.至少不是我们观察到的.嗯?

案例二:任意模式

for (pat <- expr1) yield expr2

翻译成

expr1 withFilter {
  case pat => true
  case _ => false
} map {
  case pat => expr2
}

现在有一个withFilter方法!
这种情况完全解释了错误消息以及为什么不能在Either中进行模式匹配的原因.

这一章最终指的是the scala language specification(虽然是较旧的一个),这是我现在停止的地方.

所以我很抱歉我不能完全回答这个问题,但希望我能够提示这里问题的根源是什么.

直觉

那么为什么要么有问题而且没有提出withFilter方法,其中Try和Option有用吗?
因为过滤器从“容器”中删除元素,可能是“全部”,所以我们需要一些代表“空容器”的东西.

对于Option来说这很容易,这显然是None.对于例如也很容易名单. Try不是那么容易,因为有多个Failure,每个都可以保存一个特定的异常.然而,这个地方有多次失败:

> NoSuchElementException和
> UnsupportedOperationException

这就是Try [X]运行的原因,但是[Throwable,X]不会.
这几乎是一回事,但并非完全如此.尝试知道Left是Throwable,图书馆作者可以利用它.

然而,在一个Either(现在是正确的偏见),“空”的情况是左案;这是通用的.因此,用户确定它是哪种类型,因此库作者无法为每个可能的左侧选择通用实例.

我认为这就是为什么Either没有提供开箱即用的forFilter以及为什么你的表达失败.

顺便说一句.该

expr1.map { case (x1,xn)  => expr2) }

case工作,因为它会在调用堆栈上抛出一个MatchError,并在问题中出现恐慌……这本身可能是一个更大的问题.

哦,对于那些足够勇敢的人:直到现在我还没有使用“Monad”这个词,因为Scala没有它的数据结构,但是for-comprehensions就没有它.但也许一个引用不会受到伤害:Additive Monads有这个“零”值,这正是Either在这里错过的以及我试图在“直觉”部分给出一些含义的东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读