soc*_*soc 35 scala map fold scala-option
我想知道为什么scala.Option没有fold这样定义的方法:
fold(ifSome: A => B , ifNone: => B)
Run Code Online (Sandbox Code Playgroud)
相当于
map(ifSome).getOrElse(ifNone)
Run Code Online (Sandbox Code Playgroud)
有没有比使用map+ 更好的getOrElse?
Mar*_*sky 69
我个人发现这样的方法cata需要两个闭包,因为参数往往过度.你真的获得map+ +的可读性getOrElse吗?想想你的代码的新手:他们会做些什么
opt cata { x => x + 1, 0 }
Run Code Online (Sandbox Code Playgroud)
你真的认为这比它更清楚吗?
opt map { x => x + 1 } getOrElse 0
Run Code Online (Sandbox Code Playgroud)
事实上,我认为这两者都不比优秀的老人更好
opt match {
case Some(x) => x + 1
case None => 0
}
Run Code Online (Sandbox Code Playgroud)
与往常一样,有一个限制,即额外的抽象不会给你带来好处并且会产生适得其反的效果.
Ale*_*nov 41
最后在Scala 2.10中添加了签名fold[B](ifEmpty: => B)(f: A => B): B.
不幸的是,这有一个共同的负面结果:B推断仅基于ifEmpty参数的调用,实际上通常更窄.例如(正确的版本已经在标准库中,这仅用于演示)
def toList[A](x: Option[A]) = x.fold(Nil)(_ :: Nil)
Run Code Online (Sandbox Code Playgroud)
斯卡拉将推断B是Nil.type不是期望List[A]和抱怨f没有返回Nil.type.相反,你需要一个
x.fold[List[A]](Nil)(_ :: Nil)
x.fold(Nil: List[A])(_ :: Nil)
Run Code Online (Sandbox Code Playgroud)
这fold与对应的不完全相同match.
Deb*_*ski 25
你可以做:
opt foldLeft (els) ((x, y) => fun(x))
Run Code Online (Sandbox Code Playgroud)
要么
(els /: opt) ((x,y) => fun(x))
Run Code Online (Sandbox Code Playgroud)
(两种解决方案都将按值进行评估 els ,这可能不是您想要的.感谢Rex Kerr指向它.)
编辑:
但你真正想要的是Scalaz的catamorphism cata(基本上fold不仅处理Some值而且映射None部分,这就是你所描述的)
opt.cata(fun, els)
Run Code Online (Sandbox Code Playgroud)
定义为(valuepimped选项值在哪里)
def cata[X](some: A => X, none: => X): X = value match {
case None => none
case Some(a) => some(a)
}
Run Code Online (Sandbox Code Playgroud)
这相当于opt.map(some).getOrElse(none).
虽然我应该说,只有在表达它的"更自然"的方式时才应该使用cata.在许多情况下,简单map- getOrElse足够,特别是涉及潜在链接大量的maps.(fun当然,你也可以用函数组合来链接s - 它取决于你是否要关注函数组合或值转换.)
Apo*_*isp 19
正如Debilski所提到的,你可以使用Scalaz OptionW.cata或fold.正如Jason评论的那样,命名参数使它看起来很漂亮:
opt.fold { ifSome = _ + 1, ifNone = 0 }
Run Code Online (Sandbox Code Playgroud)
现在,如果None案例中您想要的值是mzero针对某些人的,Monoid[M]并且您具有f: A => M该Some案例的函数,则可以执行以下操作:
opt foldMap f
Run Code Online (Sandbox Code Playgroud)
所以,
opt map (_ + 1) getOrElse 0
Run Code Online (Sandbox Code Playgroud)
变
opt foldMap (_ + 1)
Run Code Online (Sandbox Code Playgroud)
就个人而言,我认为Option应该有一种apply方法可以解释.那样你就可以这样做:
opt { _ + 1, 0 }
Run Code Online (Sandbox Code Playgroud)
要么
opt { some = _ + 1, none = 0 }
Run Code Online (Sandbox Code Playgroud)
实际上,对于所有代数数据结构而言,这将是很好的.