我正在寻找的是这个功能:
def maybe[A, B](a: Option[A])(f: A => B)(g: () => B): B = a match
{
case Some(x) => f(x)
case None => g()
}
这是在Haskell的前奏中所以我认为它可能在某个地方的Scala标准库中,我只是错过了它。我讨厌不得不在项目中重新编码,所以我想知道是否有人知道它在哪里,或者它是否肯定不存在。或者有更好的方法来获得此功能吗?
答案 0 :(得分:16)
其他答案给出了map
+ getOrElse
组成。只是为了记录,您可以通过以下方式向maybe
“添加”Option
功能:
implicit def optionWithMaybe[A](opt: Option[A]) = new {
def maybe[B](f: A=>B)(g: =>B) = opt map f getOrElse g
}
值得注意的是,当函数参数最后出现时,Scala中高阶函数的语法通常更好。因此,组织maybe
的更好方法如下:
def maybe[B](g: =>B)(f: A=>B) = opt map f getOrElse g
这可以使用如下:
val opt: Option[String] = ...
opt.maybe("") { _.toUpperCase }
答案 1 :(得分:14)
你可以做到
val opt:Option[A] = // ...
val result:B = opt.map(f).getOrElse(g());
getOrElse
采用名字参数,因此只有g
为opt
才会评估None
。
答案 2 :(得分:4)
如果要遵守惯例,该方法将被称为折叠(参见Either.fold,这是Either的变形)。
答案 3 :(得分:4)
您可以使用scalaz,然后隐式转换为OptionW
fold
,或者您可以使用Scala 2.10.0-M3并使用内置Option.fold
scala> Some(1).fold(5)(_ * 2)
res5: Int = 2
scala> (None: Option[Int]).fold(5)(_ * 2)
res7: Int = 5
请注意,scalaz折叠签名为fold[X](some: A => X, none: => X)
,而内置似乎为fold[X](none: => X)(some: A => X)
。
答案 4 :(得分:0)
我认为没有。我能想到的最好的方法是将Option的“map”和“getOrElse”链接在一起:
scala> var a: Option[String] = Some("hello")
a: Option[String] = Some(hello)
scala> a.map(_.toUpperCase).getOrElse("empty")
res19: java.lang.String = HELLO
scala> a = None
a: Option[String] = None
scala> a.map(_.toUpperCase).getOrElse("empty")
res21: java.lang.String = empty
答案 5 :(得分:0)
我认为没有。但是,我会将其写为g
名称:
def maybe[A, B](a: Option[A])(f: A => B)(g: => B): B = a.map(f).getOrElse(g)
这更像Scala-和Haskell,使用起来更好。
答案 6 :(得分:0)