27 votes

Pourquoi Option n'a-t-elle pas de méthode de pliage?

Je me demande pourquoi scala.Option n'a pas de méthode fold comme celle-ci définie:

 fold(ifSome: A => B , ifNone: => B)
 

équivalent à

 map(ifSome).getOrElse(ifNone)
 

N'y a-t-il rien de mieux que d'utiliser map + getOrElse ?

56voto

Martin Odersky Points 13161

Personnellement, je trouve les méthodes comme cata qui se déroule sur deux fermetures comme arguments sont souvent trop. Avez-vous vraiment gagner en lisibilité sur map + getOrElse? Pensez à un nouveau venu dans votre code: Que vont-ils faire de

opt cata { x => x + 1, 0 }

Pensez-vous vraiment que c'est plus clair que

opt map { x => x + 1 } getOrElse 0

En fait, je dirais que ni est préférable par rapport à la bonne vieille

opt match {
  case Some(x) => x + 1
  case None => 0
}

Comme toujours, il y a une limite où l'abstraction supplémentaire ne fait pas de vous donner des avantages et se tourne contre-productif.

33voto

Alexey Romanov Points 39124

Il a finalement été ajouté dans Scala 2.10 , avec la signature fold[B](ifEmpty: => B)(f: A => B): B .

21voto

Debilski Points 28586

Vous pouvez le faire:

opt foldLeft (els) ((x, y) => fun(x))

ou

(els /: opt) ((x,y) => fun(x))

(Les deux solutions évaluera els en valeur, ce qui pourrait ne pas être ce que vous voulez. Grâce à Rex Kerr pour le pointe du doigt.)

Edit:

Mais ce que vous voulez vraiment est Scalaz de catamorphism cata (en gros une fold qui ne traite pas uniquement de l' Some de la valeur, mais aussi des cartes de l' None partie, qui est ce que vous avez décrit)

opt.cata(fun, els)

définie comme (où value est le souteneur valeur de l'option)

def cata[X](some: A => X, none: => X): X = value match {
  case None => none
  case Some(a) => some(a)
}

ce qui est équivalent à opt.map(some).getOrElse(none).

Mais je dois remarquer que vous devez utiliser uniquement la cata, quand il est le "plus naturel" façon de l'exprimer. Il existe de nombreux cas où un simple mapgetOrElse suffit, surtout quand il s'agit potentiellement de chaînage beaucoup d' maps. (Bien que vous puissiez également la chaîne de l' funs avec la fonction de composition, bien sûr – cela dépend si vous voulez vous concentrer sur la fonction de la composition ou de la valeur de transformation.)

19voto

Apocalisp Points 22526

Comme mentionné par Debilski, vous pouvez utiliser Scalaz de l' OptionW.cata ou fold. Jason a commenté, les paramètres nommés faire de cette agréable à regarder:

opt.fold { ifSome = _ + 1, ifNone = 0 }

Maintenant, si la valeur que vous voulez dans l' None cas est - mzero pour certains Monoid[M] et vous avez une fonction f: A => M de la Some des cas, vous pouvez faire ceci:

opt foldMap f

Donc,

opt map (_ + 1) getOrElse 0

devient

opt foldMap (_ + 1)

Personnellement, je pense qu' Option devrait avoir un apply méthode qui serait la catamorphism. De cette façon, vous pourriez faire ceci:

opt { _ + 1, 0 }

ou

opt { some = _ + 1, none = 0 }

En fait, ce serait bien d'avoir pour tous les algébrique des structures de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X