Yann Moisan
Yann Moisan

Reputation: 8281

How to lift a partial function in an Either

I want to lift a partial function in an Either.

Is there a better way :

def lift[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)) }

Upvotes: 1

Views: 421

Answers (1)

Travis Brown
Travis Brown

Reputation: 139058

There are lots of other ways of writing this that let you avoid the unpleasant isDefinedAt:

def lift[A, B, C](pf: PartialFunction[A, B])(c: A => C): A => Either[C, B] =
  (pf andThen Right.apply) orElse (PartialFunction(c andThen Left.apply))

Or:

def lift[A, B, C](pf: PartialFunction[A, B])(c: A => C): A => Either[C, B] =
  (a: A) => pf.lift(a).fold[Either[C, B]](Left(c(a)))(Right(_))

For example.

Scalaz makes the last implementation above a little nicer with its toRight:

import scalaz._, Scalaz._

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

I'd probably go with some version of the orElse implementation, though.

Upvotes: 5

Related Questions