Pregunta

I de vez en cuando venir a través del siguiente patrón, en el que esencialmente tienen un PartialFunction[SomeType,AnotherType], y quiero tratarlo como un Function[SomeType,Option[AnotherType], por ejemplo:

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

¿Hay una manera de escribir la función anterior de una manera que evita el caso por defecto y envolviendo el resultado en Some donde se define? El mejor que he encontrado hasta el momento es la siguiente:

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)
}

¿Hay una manera de hacerlo sin definir una función intermedia? Ya lo he intentado varias cosas en la línea de lo siguiente, pero no tengo nada para compilar aún:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift
¿Fue útil?

Solución

condOpt en scala.PartialFunction objeto. Desde el scaladoc:

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

Otros consejos

No tanto una respuesta, como una explicación de por qué la respuesta es correcta huynhjl de ...

Parte de su confusión es que usted está tratando de def una función parcial. Todo esto hace es crear un método que devuelve un objeto PartialFunction, cuando usted puede también crear la cosa directamente:

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

A pesar de que personalmente prefiero tipo de uso de adscripción:

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

De cualquier manera, hay que especificar qué tipo de entrada es, por lo que tiene que dar la firma exacta de la PartialFunction. Sé que se siente como que debería ser posible inferir esto, pero, por desgracia, eso no es tristemente el caso!

El uso de la versión atribuida, a continuación, puede definir y levantar todos en el mismo lugar:

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

PartialFunction.condOpt es la mejor solución, sin embargo, ya que permite al inferencer hacer la mayor parte de este trabajo para usted, dejando mucho código más limpio:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top