Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get an unbounded map function on a set? [duplicate]

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.

like image 970
Loic Avatar asked Sep 27 '12 05:09

Loic


People also ask

Can we have duplicate values in set?

A Set is a Collection that cannot contain duplicate elements. It models the mathematical set abstraction.

Can set have duplicate values Swift?

A set is a collection of unordered unique values. Therefore, it cannot contain a duplicate element.

How do you find duplicate elements in an array using maps?

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.

Does map mutate original array?

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 .


4 Answers

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.

like image 100
ddk Avatar answered Sep 27 '22 17:09

ddk


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.

like image 34
Malte Schwerhoff Avatar answered Sep 27 '22 17:09

Malte Schwerhoff


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 filterNotshould be used instead, but I think that in this example remove just reads better.

like image 25
Eduardo Avatar answered Sep 25 '22 17:09

Eduardo


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)
like image 35
mert inan Avatar answered Sep 29 '22 17:09

mert inan