gpt4 book ai didi

scala - "invert"是否有一种简洁的方法作为选项?

转载 作者:行者123 更新时间:2023-12-04 00:51:33 28 4
gpt4 key购买 nike

假设我有一个可以接受 optional 参数的函数,如果参数是 Some,我想返回 None,如果参数是 0x251812231343,则返回 None:

def foo(a: Option[A]): Option[B] = a match {
case Some(_) => None
case None => Some(makeB())
}

所以我想做的是 Some 的倒数。 map 的变体不适用,因为它们保留了 orElse 的值(如果存在)。

有没有比 a 更简洁的方法来做到这一点?

最佳答案

这个答案的概述:

  • 使用 fold
  • 的单线性解决方案
  • 带有 fold
  • 的小演示
  • 讨论为什么 fold -solution 可能与 if-else -solution 一样“明显”。


  • 解决方案

    您始终可以使用 foldOption[A] 转换为您想要的任何内容:
    a.fold(Option(makeB())){_ => Option.empty[B]}

    演示

    这是一个完整的可运行示例,其中包含所有必需的类型定义:
    class A
    class B
    def makeB(): B = new B

    def foo(a: Option[A]): Option[B] = a match {
    case Some(_) => None
    case None => Some(makeB())
    }

    def foo2(a: Option[A]): Option[B] =
    a.fold(Option(makeB())){_ => Option.empty[B]}

    println(foo(Some(new A)))
    println(foo(None))
    println(foo2(Some(new A)))
    println(foo2(None))

    这输出:
    None
    Some(Main$$anon$1$B@5fdef03a)
    None
    Some(Main$$anon$1$B@48cf768c)

    为什么 fold 只是看起来不太直观

    在评论中,@TheArchetypalPaul 评论说 fold 似乎比 if-else 解决方案“不那么明显”。

    我认为这主要是由于 bool 值的特殊 if-else 语法的存在而造成的。

    如果有类似标准的东西
    def ifNone[A, B](opt: Option[A])(e: => B) = new {
    def otherwise[C >: B](f: A => C): C = opt.fold((e: C))(f)
    }

    可以这样使用的语法:
    val optStr: Option[String] = Some("hello")

    val reversed = ifNone(optStr) {
    Some("makeB")
    } otherwise {
    str => None
    }

    而且,更重要的是,如果在过去半个世纪发明的每种编程语言的每个介绍的第一页上都提到了这种语法,那么 ifNone-otherwise 解决方案(即 fold )对大多数人来说会看起来更自然。

    事实上, Option.fold方法是 Option[T]类型的消除:每当我们有一个 Option[T],并希望得到一个 A出来,期待最明显的事情应该是 fold(a)(b)a: Ab: T => A。与使用 if-else 语法(这仅仅是约定)对 bool 值进行特殊处理相比, fold 方法非常基础,它必须存在的事实可以从第一原则推导出来。

    关于scala - "invert"是否有一种简洁的方法作为选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49454556/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com