Is there a standard way to complete a partial function PartialFunction[A, B]? Something like this:
completePartialFunction(pf: PartialFunction[A, B], z: B): A => B
or
completePartialFunction2(pf: PartialFunction[A, B], f: A => B): A => B
Yes, it's actually very simple:
def complete[A, B](pf: PartialFunction[A, B])(f: A => B): A => B =
pf.applyOrElse(_, f)
You can use lift method on PartialFunction, that returns Option[B]. So when the function is not defined for the input, None is returned. You can find more in the scaladocs.
Other solution that comes to my mind is when you're using cats or scalaz. You can then check whether the function is defined for the argument and when not, return empty from the Monoid[B] that you should pass (probably implicitly) to completePartialFunction.
If I understand the question, you want to use f() to supplement pf() so that all possible values of type A are covered.
def completePartialFunction2[A,B](pf : PartialFunction[A,B]
,f : A => B): A => B =
(a:A) => if (pf.isDefinedAt(a)) pf(a) else f(a)
Another simple version:
def completePartialFunction[A, B](pf: PartialFunction[A, B], f: A => B): A => B
= pf orElse { case a: A => f(a) }
Related
I have several generic functions with the same signature:
def f1[A, B](v: A, f: (A, B) => B): B = ...
def f2[A, B](v: A, f: (A, B) => B): B = ...
And I need to define a function g that can accept any of these functions (f1 f2):
def g(f: ????) = ...
g internally uses multiple argument types, so I can not parameterize it like that:
def g[A, B](f: (A, (A, B) => B) => B) = ...
There isn't really a much better way to do it in Scala 2. Although your solution is a bit strange because FunctionHolder's apply method will return a function object and doesn't accept any arguments itself – that's a bit more complicated than it needs to be. So you can do this instead:
trait FunctionHolder {
def apply[A, B](v: A, f: (A, B) => B): B
}
def g(f: FunctionHolder) = …
But this isn't really all that much better.
In Scala 3, there are polymorphic function types to do this in a cleaner way:
def g(f: [A, B] => (A, (A, B) => B) => B) = …
That said, I'm not convinced that that type signature is really what you want. Remember, when you define a function with type parameters, it needs to work for all possible type parameters that the user might supply. This can't be done for this signature…
def f1[A, B](v: A, f: (A, B) => B): B
… because when I have a function like that, I can easily write an expression of type Nothing:
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)
and it's not possible to write an expression of type Nothing unless you cheat (e. g. throw an exception or enter an infinite loop or something like that). So the type signature tells me you're cheating 😉
If you want to know more about this kind of reasoning, search for “Theorems for free!”
After wandering a bit, come up with following:
g(new FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B = f1
})
def g(f: FunctionHolder) = f()(..., (a, b) => ...)
abstract class FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B
}
But that just does not look right.
Hope there are more concise ways to do that
Suppose I've got a list of functions List[A => B] and need a function that returns List[B] for a given value of type A:
def foo[A, B](fs: List[A => B]): A => List[B] = a => fs.map(_.apply(a))
Is there any simpler (maybe with cats) way to write List[A => B] => A => List[B] ?
As #Oleg points out, you can use Applicative to generate the function:
import cats.implicits._
def foo[A, B](fs: List[A => B]): A => List[B] = a => fs ap List(a)
Although I don't think it makes much of a difference in this particular case.
The signature of f (a -> b) -> a -> f b suggests to use flap (from Haskell).
Starting from 2.9.0 you can use its equivalent in Cats named mapApply.
import cats.implicits._
def foo[A, B](fs: List[A => B]): A => List[B] = a => fs.mapApply(a)
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)) }
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.
Given a val that consists of the following (what I believe is a) type constructor with a curried function argument, F[A => B => C]...
val x: F[A => B => C] = foo() // foo does not matter
Is it possible for me to get F[C] from x?
val y: F[C] = x...
EDIT
For context, I'm trying to implement the map3 function from Functional Programming in Scala.
The only way to get F[C] from F[A => B => C] is if you can apply an A and a B to it. That is, you'll need to evaluate the contained function. Use the apply twice, once to get an B => C and then once again to get C.
def eval(myApp: F[A => B => C])(value: F[A]): F[B => C]
def evalAgain(myApp: F[B => C])(value: F[B]): F[C]
but if you just want to be able to get F[C] directly from the function itself without evaluation, you're SOL.
Edit:
I believe it would look like this.
def eval(myApp: F[A => B => C])(value: F[A], next: F[B])(implicit ap: Applicative[F[_]]) = ap(ap(myApp, value), next)
Does there exist a utility in Scala or Scalaz to transform a container/collection of functions to a function that maps from the same input to a collection output values? The signature would look something like
def transform[M[_], A, B](m: M[A => B]): A => M[B] = ???
Here's an example implementation for the List container:
def transform[A, B](fs: List[A => B]): A => List[B] = x =>
fs.foldRight[List[B]](Nil) {
(f, acc) => f(x) :: acc
}
Ideally, this would work for any function container, including a tuple of functions, an Option[Function1[A, B]], or even a TupleN[Option[Function1[A, B]], ...].
EDIT:
I've just realized that (at least for the special case of a List) the map function works:
def transform[A, B](fs: List[A => B]): A => List[B] = x => fs map (_(x))
This can generalize to anything that has a map function with the appropriate semantics. What's the appropriate type class for this?
Assuming M is a Functor, mapply in scalaz's Functor has a similar type signature:
def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)((ff: A => B) => ff(a))
So you could write transform in terms of that:
def transform[M[_],A,B](m: M[A => B])(implicit f:Functor[M]):A => M[B] = f.mapply(_)(m)
Edit: Another implementation using features from FunctorSyntax:
def transform[M[_]:Functor,A,B](m: M[A => B]):A => M[B] = _.mapply(m)
I searched through the Scalaz source code and it looks like Functor does the trick:
def transform[M[_]: Functor, A, B](fs: M[A => B]): A => M[B] = a => fs map (_(a))