Is there a way to express the inverse of any function in Scala?
For example if I have a function f
like this:
(x: Int) => x + 1
I would like to be able write an inverse function g
like:
(f(x): Int) => x // not a valid scala syntax
or
(x: Int) => inverse(f(x)) // inverse would return (x => x -1)
Do you know a way to do this kind of thing in Scala?
N.B: x => x+1
is just for the example. I'm looking for a generic way to solve this kind of task.
A Set is a Collection that cannot contain duplicate elements. It models the mathematical set abstraction.
A set is a collection of unordered unique values. Therefore, it cannot contain a duplicate element.
How To Find Duplicate Elements In Array In Java Using HashMap? In this method, We use HashMap to find duplicates in array in java. We store the elements of input array as keys of the HashMap and their occurrences as values of the HashMap. If the value of any key is more than one (>1) then that key is duplicate element.
map does not mutate the array on which it is called (although callbackFn , if invoked, may do so). The range of elements processed by map is set before the first invocation of callbackFn .
No, something like that is not possible. The problem is that not all mathematical functions have inverses. From the Wikipedia entry on inverse functions:
Not all functions have an inverse. For this rule to be applicable, each element y ∈ Y must correspond to no more than one x ∈ X; a function ƒ with this property is called one-to-one, or information-preserving, or an injection.
For example, the square root (sqrt
) function is the inverse of the square function (x^2
) only when x >= 0
, where the square root function is one-to-one. We can say that the negative of the square root function is the inverse of the square function when x < 0
only because x^2 = (-x)^2
. But that is a special property of the square function and is certainly not true in general.
Depending on your usage scenario you might be able to sort of do this by maintaining a map from (Function, Result) => Arguments
, and then call a method such as inverse(f, r)
which returns the arguments as stored in the map. However, this only works 1) if the original function is invoked before the inverse value is needed and 2) if the original function is injective (as ddk already pointed out).
There also is quite some implementation overhead involved (for example, you probably need a dedicated map for Function1
to Function22
), especially if you want to reduce the amount of boilerplate code imposed on function implementers. Aspect-oriented programming could help here, annotations similar to EJB3's Interceptors might also work.
It looks, though, as if the usage scenario must be a pretty special one to justify all the hoops you have to jump through.
You cannot express the inverse of a function, but you can express the inverse of its result and perhaps that would suit you.
This can be useful when you are passing the function around.
For example, if you have a function f: Int => Boolean
that you're using as a parameter in a higher order function, you can wrap it in another function of the same type x => !f(x)
that justs returns the inverse of the computed result:
def select(ls: List[String], p: String => Boolean): List[String] =
ls.remove(x => !p(x))
// select: (ls: List[String], p: String => Boolean)List[String]
val li = List("one", "two", "three")
// li: List[java.lang.String] = List(one, two, three)
/* using select with some conditions */
select(li, _.length() > 3) // equivalent to select(li, x => x.length() > 3)
// res0: List[String] = List(three)
select(li, _.length() <= 3) // equivalent to select(li, x => x.length() <= 3)
// res1: List[String] = List(one, two)
/* using remove with the same conditions */
li.remove(_.length() > 3) // equivalent to li.remove(x => x.length() > 3)
// res2: List[java.lang.String] = List(one, two)
li.remove(_.length() <= 3) // equivalent to li.remove(x => x.length() <= 3)
// res3: List[java.lang.String] = List(three)
NOTE: method remove
in class List
is deprecated and filterNot
should be used instead, but I think that in this example remove
just reads better.
From pragmatistic view, unapply
method could be used to represent inverse functions:
object f {
def apply(x: Int) = x + 1
def unapply(x: Int) = Some(x - 1);
}
val x = 1
val f(y) = f(x)
assert(x == y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With