Интересно, почему scala.Option
не имеет метода fold
, как это определено:
fold(ifSome: A => B , ifNone: => B)
эквивалентно
map(ifSome).getOrElse(ifNone)
Не лучше ли использовать map
+ getOrElse
?
Интересно, почему scala.Option
не имеет метода fold
, как это определено:
fold(ifSome: A => B , ifNone: => B)
эквивалентно
map(ifSome).getOrElse(ifNone)
Не лучше ли использовать map
+ getOrElse
?
Вы можете сделать:
opt foldLeft (els) ((x, y) => fun(x))
или
(els /: opt) ((x,y) => fun(x))
(Оба решения оценивают значение els
по значению, что может и не быть тем, что вы хотите. Благодаря Rex Kerr для указания на него.)
Edit:
Но то, что вы действительно хотите, это Scalazs catamorphism cata
(в основном a fold
, который обрабатывает не только Some
но также отображает часть None
, что вы описали)
opt.cata(fun, els)
определяемый как (где value
- значение оплошности)
def cata[X](some: A => X, none: => X): X = value match {
case None => none
case Some(a) => some(a)
}
что эквивалентно opt.map(some).getOrElse(none)
.
Хотя я должен заметить, что вы должны использовать только cata, когда это "более естественный способ выразить это". Существует много случаев, когда достаточно простого map
- getOrElse
, особенно когда оно связано с потенциальной цепью партий map
s. (Хотя вы могли бы также цепью fun
с составом функций, конечно же - это зависит от того, хотите ли вы сосредоточиться на композиции функции или преобразовании значения.)
Я лично нахожу такие методы, как cata
, которые принимают два закрытия, поскольку аргументы часто переусердствуют. Вы действительно получаете удобочитаемость над map
+ getOrElse
? Подумайте о новичке в своем коде: что они сделают из
opt cata { x => x + 1, 0 }
Вы действительно думаете, что это яснее, чем
opt map { x => x + 1 } getOrElse 0
На самом деле я бы сказал, что ни один из них не предпочтительнее старого старого
opt match {
case Some(x) => x + 1
case None => 0
}
Как всегда, существует предел, где дополнительная абстракция не дает вам преимуществ и становится контрпродуктивной.
В конце было добавлено в Scala 2.10 с подписью fold[B](ifEmpty: => B)(f: A => B): B
.
Как упоминалось Debilski, вы можете использовать Scalaz OptionW.cata
или fold
. Как прокомментировал Джейсон, названные параметры делают этот взгляд приятным:
opt.fold { ifSome = _ + 1, ifNone = 0 }
Теперь, если значение, которое вы хотите в случае None
, mzero
для некоторого Monoid[M]
, и у вас есть функция f: A => M
для случая Some
, вы можете сделать это:
opt foldMap f
Итак,
opt map (_ + 1) getOrElse 0
становится
opt foldMap (_ + 1)
Лично я думаю, что Option
должен иметь метод apply
, который был бы катаморфизмом. Таким образом, вы можете просто сделать это:
opt { _ + 1, 0 }
или
opt { some = _ + 1, none = 0 }
На самом деле это было бы неплохо иметь для всех структур алгебраических данных.