2015-03-11 2 views
3
à fonction partielle

Il n'y a pas de fonction intégrée dans l'API Scala pour soulever un PartialFunction à Either.Comment soulever un ou l'autre

Voici ma version:

def liftToEither[A, B, C](pf: PartialFunction[A, B])(c: A => C) : A => Either[C, B] = { a => 
    if (pf.isDefinedAt(a)) Right(pf(a)) else Left(c(a)) 
    } 

Y at-il une meilleure façon?

+0

Vous ne pouvez pas utiliser intégré 'Either.cond (pf.isDefinedAt (a), pf (a), c (a)) '? ou peut-être ai-je mal compris votre question? – ale64bit

+0

@kaktusito Oui, cela fonctionnerait. Mais tout comme la proposition OPs, elle évaluera 'pf' deux fois, ce qui peut être indésirable. – gzm0

+0

Est-ce que cela répond à votre question? –

Répondre

3

Vous pouvez utiliser lift et toRight. Je ne suis pas sûr si je l'appellerais mieux.

def liftToEither[A, B, C](pf: PartialFunction[A, B])(c: A => C) : A => Either[C, B] = 
    a => pf.lift(a).toRight(c(a)) 

lift transformera PartialFunction[A, B] en A => Option[B]. Ensuite, nous pouvons appliquer cette fonction à a levée pour obtenir Option[B], et utiliser toRight pour transformer Some(b)-Right(b) et appliquer c-a pour les instances de None pour obtenir le Left(c(a)).

1

Si vous êtes à la recherche d'une solution qui compose tout PartialFunctions (et ne crée pas de fermeture sur lui-même), essayez ceci:

def liftToEither[A, B, C](pf: PartialFunction[A, B])(c: A => C) : A => Either[C, B] = { 
    val fallback = PartialFunction((x: A) => Left(c(x))) 
    pf.andThen(Right(_)).orElse(fallback) 
} 
0
import scala.util.{ Try, Success, Failure } 

def liftToEither[A, B, C](pf: PartialFunction[ A, B ]) 
         (c: A => C) : A => Either[ C, B ] = { a => 
    val trial = Try(pf(a)) 
    trial match { 
    case Success(b) => Right(b) 
    case Failure(ex) => Left(c(a)) 
    } 
}