Question

Je viens de temps en temps à travers le schéma suivant, où j'ai essentiellement un PartialFunction[SomeType,AnotherType], et que vous voulez le traiter comme un Function[SomeType,Option[AnotherType], par exemple:

def f(s:SomeType):Option[AnotherType] = s match {
  case s1:SubType1 => Some(AnotherType(s1.whatever))
  case s2:SubType2 => Some(AnotherType(s2.whatever))
  case _ => None
}

Est-il possible d'écrire la fonction ci-dessus d'une manière qui évite le cas par défaut et envelopper le résultat dans Some où il est défini? Le meilleur que je suis venu avec à ce jour est la suivante:

def f(s:SomeType):Option[AnotherType] = pf.lift(s)
def pf:PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

Est-il possible de le faire sans définir une fonction intermédiaire? Je l'ai déjà essayé différentes choses le long des lignes de ce qui suit, mais n'ai rien à compiler encore:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift
Était-ce utile?

La solution

condOpt dans scala.PartialFunction d'objet. De l'scaladoc:

def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }

Autres conseils

Pas tellement une réponse, comme une explication des raisons pour lesquelles la réponse de huynhjl est correcte ...

Une partie de votre confusion est que vous essayez de def une fonction partielle. Tout cela fait est de créer une méthode qui retourne un objet PartialFunction, lorsque vous pouvez ainsi créer directement la chose:

val pf: PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

Bien que je préfère personnellement utiliser le type ascription:

val pf = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]

De toute façon, vous devez spécifier ce type d'entrée est, donc vous devez donner la signature exacte du PartialFunction. Je sais qu'il se sent comme il devrait être possible de déduire cela, mais, hélas, qui est malheureusement pas le cas!

En utilisant la version attribuée, vous pouvez définir et soulever tout au même endroit:

val pf = ({
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]).lift

PartialFunction.condOpt est la meilleure solution si, car il permet au inferencer de faire plus de ce travail pour vous, en laissant beaucoup de code de nettoyage:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top