Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if implicit conversion is available

I am trying to detect if an implicit conversion exists, and depending on it, to execute some code. For instance :

if (x can-be-converted-to SomeType)
  return something(conversion(x))
else
  return someotherthing(x)

For instance, x is an Int and should be converted to a RichInt. Is this possible in Scala? If yes, how?

Thanks

like image 995
Alban Linard Avatar asked Apr 19 '11 14:04

Alban Linard


People also ask

What two commands will perform implicit conversion?

Answer: Cast and Convert. Cast and convert play an integral partnership with any data type function as they convert an expression of one data type to another.

What is implicit conversion in SQL?

Implicit conversions are not visible to the user. SQL Server automatically converts the data from one data type to another. For example, when a smallint is compared to an int, the smallint is implicitly converted to int before the comparison proceeds.

What is an implicit conversion?

An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.

What is implicit casting C++?

Implicit type conversion also known as automatic type conversion is carried out by the compiler without the need for a user-initiated action. It takes place when an expression of more than one data type is present which in such an instance type conversion takes place to avoid data loss.


2 Answers

As others already mentioned implicits are resolved at compile time so maybe you should rather use type classes to solve problems like this. That way you have the advantage that you can extend functionality to other types later on.

Also you can just require an existing implicit value but have no way of directly expressing non-existence of an implicit value except for the default arguments.

Jean-Phiippe's solution using a default argument is already quite good but the null could be eliminated if you define a singleton that can be put in place of the implicit parameter. Make it private because it is actually of no use in other code and can even be dangerous as implicit conversions can happen implicitly.

private case object NoConversion extends (Any => Nothing) {
   def apply(x: Any) = sys.error("No conversion")
}

// Just for convenience so NoConversion does not escape the scope.
private def noConversion: Any => Nothing = NoConversion

// and now some convenience methods that can be safely exposed:

def canConvert[A,B]()(implicit f: A => B = noConversion) =
  (f ne NoConversion)

def tryConvert[A,B](a: A)(implicit f: A => B = noConversion): Either[A,B] = 
  if (f eq NoConversion) Left(a) else Right(f(a))

def optConvert[A,B](a: A)(implicit f: A => B = noConversion): Option[B] =
  if (f ne NoConversion) Some(f(a)) else None
like image 78
Moritz Avatar answered Sep 29 '22 04:09

Moritz


You can try to pass it to a method that needs the corresponding implicit parameter with a default of null:

def toB[A](a: A)(implicit convertFct: A => B = null) =
  if (convertFct != null)
    convertFct(a)
  else
    someOtherThing(a)

Note that it looks curious to me to check this at runtime, because the compiler knows at compile time whether such a conversion function is available.

like image 43
Jean-Philippe Pellet Avatar answered Sep 29 '22 03:09

Jean-Philippe Pellet