C'è un modo migliore di sollevare una funzione parziale a Scala?
-
12-10-2019 - |
Domanda
Di tanto in tanto venire attraverso il seguente schema, dove ho in sostanza ho un PartialFunction[SomeType,AnotherType]
, e voglio trattarlo come un Function[SomeType,Option[AnotherType]
, ad esempio:
def f(s:SomeType):Option[AnotherType] = s match {
case s1:SubType1 => Some(AnotherType(s1.whatever))
case s2:SubType2 => Some(AnotherType(s2.whatever))
case _ => None
}
C'è un modo per scrivere la funzione di cui sopra in modo da evitare il caso di default e avvolgendo il risultato in Some
dove è definito? Il migliore che è venuta in mente finora è questa:
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)
}
C'è un modo per farlo senza definire una funzione intermedia? Ho già provato varie cose sulla falsariga di quanto segue, ma non ho niente per compilare ancora:
def f:Function[SomeType,Option[AnotherType]] = {
case s1:SubType1 => AnotherType(s1.whatever)
case s2:SubType2 => AnotherType(s2.whatever)
}.lift
Soluzione
condOpt
in oggetto scala.PartialFunction. Dal scaladoc:
def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }
Altri suggerimenti
Non tanto una risposta, come una spiegazione del perché di huynhjl risposta è corretta ...
Parte della vostra confusione è che si sta cercando di def
una funzione parziale. Tutto questo non è quello di creare un metodo che restituisce un oggetto PartialFunction
, quando si può anche creare la cosa direttamente:
val pf: PartialFunction[SomeType,AnotherType] = {
case s1:SubType1 => AnotherType(s1.whatever)
case s2:SubType2 => AnotherType(s2.whatever)
}
Anche se io personalmente preferisco tipo uso attribuzione:
val pf = {
case s1:SubType1 => AnotherType(s1.whatever)
case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]
In entrambi i casi, è necessario specificare che il tipo di ingresso è, quindi bisogna dare la firma esatta del PartialFunction
. So che ci si sente come dovrebbe essere possibile dedurre questo, ma, ahimè, che non è purtroppo il caso!
Utilizzando la versione attribuito, si può quindi definire e sollevare tutti nello stesso posto:
val pf = ({
case s1:SubType1 => AnotherType(s1.whatever)
case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]).lift
PartialFunction.condOpt
è la soluzione migliore, anche se, in quanto consente l'inferencer per fare la maggior parte di questo lavoro per voi, lasciando codice più pulito molto:)