Is there a way to have this done implicitly? - scala

Is there any way to have this implicit method called on x before it matches to meet the type requirements of the match?
If I call it directly it works as expected, but I would like to know if it's possible for the call to be inferred.
object ImplicitTest extends App {
implicit def denull[T<:Any](mightBeNull:T):Option[T] = {
if (mightBeNull == null) None
else Some(canBeNull)
}
var x:String = null
x match { //works if i do "denull(x) match {"
case Some(str:String) =>
println(str)
case None => None
}
}

Instead of your denull method you should use Option.apply. It does the same thing. Possible null values should always be handled explicitly! Implicit conversion is dangerous and can be confusing for other people who have to work with your code. Do it like this:
Option(x) match {}
or in most cases even better:
Option(x).fold { ... } { ... }

You can wrap this with method which uses implicit convertion if you want:
def print[A](opt: Option[A]) = opt.foreach(println)
When you call this method on variable with null value, Scala compiler resolves your implicit convertion method denull, and if it isn't None, will print it.
But you can simply do this without denull method:
var str: String = null
Option(str).foreach(println)
Scala won't resolve implicit conversion in pattern matching, because has no idea that it needs to be converted to some other type. Such way of conversion is a mechanism against type errors, when compiler can do "the last try" and use some value with type A in place where type B needed. In pattern matching you just match against type or other things

Related

Implicit conversions weirdness

I am trying to understand why exactly an implicit conversion is working in one case, but not in the other.
Here is an example:
case class Wrapper[T](wrapped: T)
trait Wrapping { implicit def wrapIt[T](x: Option[T]) = x.map(Wrapper(_))
class NotWorking extends Wrapping { def foo: Option[Wrapper[String]] = Some("foo") }
class Working extends Wrapping {
def foo: Option[Wrapper[String]] = {
val why = Some("foo")
why
}
}
Basically, I have an implicit conversion from Option[T] to Option[Wrapper[T]], and am trying to define a function, that returns an optional string, that gets implicitly wrapped.
The question is why, when I try to return Option[String] directly (NotWorking above), I get an error (found : String("foo") required: Wrapper[String]), that goes away if I assign the result to a val before returning it.
What gives?
I don't know if this is intended or would be considered a bug, but here is what I think is happening.
In def foo: Option[Wrapper[String]] = Some("foo") the compiler will set the expected type of the argument provided to Some( ) as Wrapper[String]. Then it sees that you provided a String which it is not what is expected, so it looks for an implicit conversion String => Wrapper[String], can't find one, and fails.
Why does it need that expected type stuff, and doesn't just type Some("foo") as Some[String] and afterwards try to find a conversion?
Because scalac wants to be able to typecheck the following code:
case class Invariant[T](t: T)
val a: Invariant[Any] = Invariant("s")
In order for this code to work, the compiler can't just type Invariant("s") as Invariant[String] because then compilation will fail as Invariant[String] is not a subtype of Invariant[Any]. The compiler needs to set the expected type of "s" to Any so that it can see that "s" is an instance of Any before it's too late.
In order for both this code and your code to work out correctly, I think the compiler would need some kind of backtracking logic which it doesn't seem to have, perhaps for good reasons.
The reason that your Working code does work, is that this kind of type inference does not span multiple lines. Analogously val a: Invariant[Any] = {val why = Invariant("s"); why} does not compile.

Why does creating a map function whose parameter is of type `Nothing => U` appear to work?

I'm writing Scala code that uses an API where calls to the API can either succeed, fail, or return an exception. I'm trying to make an ApiCallResult monad to represent this, and I'm trying to make use of the Nothing type so that the failure and exception cases can be treated as a subtype of any ApiCallResult type, similar to None or Nil. What I have so far appears to work, but my use of Nothing in the map and flatMap functions has me confused. Here's a simplified example of what I have with just the map implementation:
sealed trait ApiCallResult[+T] {
def map[U]( f: T => U ): ApiCallResult[U]
}
case class ResponseException(exception: APICallExceptionReturn) extends ApiCallResult[Nothing] {
override def map[U]( f: Nothing => U ) = this
}
case object ResponseFailure extends ApiCallResult[Nothing] {
override def map[U]( f: Nothing => U ) = ResponseFailure
}
case class ResponseSuccess[T](payload: T) extends ApiCallResult[T] {
override def map[U]( f: T => U ) = ResponseSuccess( f(payload) )
}
val s: ApiCallResult[String] = ResponseSuccess("foo")
s.map( _.size ) // evaluates to ResponseSuccess(3)
val t: ApiCallResult[String] = ResponseFailure
t.map( _.size ) // evaluates to ResponseFailure
So it appears to work the way I intended with map operating on successful results but passing failures and exceptions along unchanged. However using Nothing as the type of an input parameter makes no sense to me since there is no instance of the Nothing type. The _.size function in the example has type String => Int, how can that be safely passed to something that expects Nothing => U? What's really going on here?
I also notice that the Scala standard library avoids this issue when implementing None by letting it inherit the map function from Option. This only furthers my sense that I'm somehow doing something horribly wrong.
Three things are aligning to make this happen, all having to do with covariance and contravariance in the face of a bottom type:
Nothing is the bottom type for all types, e.g. every type is its super.
The type signature of Function1[-T, +R], meaning it accepts any type which is a super of T and returns any type for which R is a super.
The type ApiCallResult[+R] means any type U for which R is a super of U is valid.
So any type is a super of Nothing means both any argument type is valid and the fact that you return something typed around Nothing is a valid return type.
I suggest that you don't need to distinguish failures and exceptions most of the time.
type ApiCallResult[+T] = Try[T]
case class ApiFailure() extends Throwable
val s: ApiCallResult[String] = Success("this is a string")
s.map(_.size)
val t: ApiCallResult[String] = Failure(new ApiFailure)
t.map(_.size)
To pick up the failure, use a match to select the result:
t match {
case Success(s) =>
case Failure(af: ApiFailure) =>
case Failure(x) =>
}

implement conversion parameters function with scala

I'm trying to implement something like clever parameters converter function with Scala.
Basically in my program I need to read parameters from a properties file, so obviously they are all strings and I would like then to convert each parameter in a specific type that I pass as parameter.
This is the implementation that I start coding:
def getParam[T](key : String , value : String, paramClass : T): Any = {
value match {
paramClass match {
case i if i == Int => value.trim.toInt
case b if b == Boolean => value.trim.toBoolean
case _ => value.trim
}
}
/* Exception handling is missing at the moment */
}
Usage:
val convertedInt = getParam("some.int.property.key", "10", Int)
val convertedBoolean = getParam("some.boolean.property.key", "true", Boolean)
val plainString = getParam("some.string.property.key", "value",String)
Points to note:
For my program now I need just 3 main type of type: String ,Int and Boolean,
if is possible I would like to extends to more object type
This is not clever, cause I need to explicit the matching against every possibile type to convert, I would like an more reflectional like approach
This code doesn't work, it give me compile error: "object java.lang.String is not a value" when I try to convert( actually no conversion happen because property values came as String).
Can anyone help me? I'm quite newbie in Scala and maybe I missing something
The Scala approach for a problem that you are trying to solve is context bounds. Given a type T you can require an object like ParamMeta[T], which will do all conversions for you. So you can rewrite your code to something like this:
trait ParamMeta[T] {
def apply(v: String): T
}
def getParam[T](key: String, value: String)(implicit meta: ParamMeta[T]): T =
meta(value.trim)
implicit case object IntMeta extends ParamMeta[Int] {
def apply(v: String): Int = v.toInt
}
// and so on
getParam[Int](/* ... */, "127") // = 127
There is even no need to throw exceptions! If you supply an unsupported type as getParam type argument, code will even not compile. You can rewrite signature of getParam using a syntax sugar for context bounds, T: Bound, which will require implicit value Bound[T], and you will need to use implicitly[Bound[T]] to access that values (because there will be no parameter name for it).
Also this code does not use reflection at all, because compiler searches for an implicit value ParamMeta[Int], founds it in object IntMeta and rewrites function call like getParam[Int](..., "127")(IntMeta), so it will get all required values at compile time.
If you feel that writing those case objects is too boilerplate, and you are sure that you will not need another method in these objects in future (for example, to convert T back to String), you can simplify declarations like this:
case class ParamMeta[T](f: String => T) {
def apply(s: String): T = f(s)
}
implicit val stringMeta = ParamMeta(identity)
implicit val intMeta = ParamMeta(_.toInt)
To avoid importing them every time you use getParam you can declare these implicits in a companion object of ParamMeta trait/case class, and Scala will pick them automatically.
As for original match approach, you can pass a implicit ClassTag[T] to your function, so you will be able to match classes. You do not need to create any values for ClassTag, as the compiler will pass it automatically. Here is a simple example how to do class matching:
import scala.reflect.ClassTag
import scala.reflect._
def test[T: ClassTag] = classTag[T].runtimeClass match {
case x if x == classOf[Int] => "I'm an int!"
case x if x == classOf[String] => "I'm a string!"
}
println(test[Int])
println(test[String])
However, this approach is less flexible than ParamMeta one, and ParamMeta should be preferred.

Scala - how to create a single implicit that can be used for a type constructor

I'm trying to write a method which uses the isEmpty method on types String, Option and List. These classes don't share a common base trait with that method, so I've tried to pass an implicit EmptyChecker in with them:
trait EmptyChecker[Field] {
def isEmpty(data: Field): Boolean
}
implicit val StringEmptyChecker: EmptyChecker[String] = new EmptyChecker[String] {
def isEmpty(string: String): Boolean = string.isEmpty
}
def printEmptiness[Field](field: Field)(implicit emptyChecker: EmptyChecker[Field]): Unit = {
if (emptyChecker.isEmpty(field))
println("Empty")
else
println("Not empty")
}
printEmptiness("abc") // Works fine
The String empty checker works fine, but I've hit problems with making empty checkers for type constructors like Option and List.
For example, Option doesn't work:
implicit val OptionChecker: EmptyChecker[Option[_]] = new EmptyChecker[Option[_]] {
def isEmpty(option: Option[_]): Boolean = option.isEmpty
}
// Both fail compilation: "could not find implicit value for parameter emptyChecker: EmptyChecker[Some[Int]]
printEmptiness(Some(3))
printEmptiness[Option[Int]](Some(3))
If I use a specific Option[Int] checker, it works a little better, but is a bit ugly:
implicit val OptionIntChecker: EmptyChecker[Option[Int]] = new EmptyChecker[Option[Int]] {
def isEmpty(optionInt: Option[Int]): Boolean = optionInt.isEmpty
}
// Fails like above:
printEmptiness(Some(3))
// Passes compilation:
printEmptiness[Option[Int]](Some(3))
So my question is: is it possible to make a single EmptyChecker for each Option and List type and have them work with my method without needing to explicitly declare the type whenever I call it? I'm trying to get a type safe duck typing effect.
I'm using scala 2.11.6.
Thanks in advance!
The source of your problem is that the type of Some(1) is Some[Int], not Option[Int]. There are a couple of ways around this; you can explicitly upcast the expression with a type ascription: printEmptiness(Some(3): Option[Int]). Alternatively, you can define a helper method to do this for you automatically, and if you're using Scalaz, there's one of these provided:
import scalaz.syntax.std.option._
printEmptiness(3.some)
Furthermore if you do use Scalaz, you may find looking at the PlusEmpty/ApplicativePlus/MonadPlus type classes useful.

Scala Implicit parameters by passing a function as argument To feel the adnvatage

I try to feel the advantage of implicit parameters in Scala. (EDITED: special case when anonymous function is used. Please look at the links in this question)
I try to make simple emulation based on this post. Where explained how Action works in PlayFramework. This also related to that.
The following code is for that purpose:
object ImplicitArguments extends App {
implicit val intValue = 1 // this is exiting value to be passed implicitly to everyone who might use it
def fun(block: Int=>String): String = { // we do not use _implicit_ here !
block(2) // ?? how to avoid passing '2' but make use of that would be passed implicitly ?
}
// here we use _implicit_ keyword to make it know that the value should be passed !
val result = fun{ implicit intValue => { // this is my 'block'
intValue.toString // (which is anonymous function)
}
}
println(result) // prints 2
}
I want to get "1" printed.
How to avoid passing magic "2" but use "1" that was defined implicitly?
Also see the case where we do not use implicit in definition, but it is there, because of anonymous function passing with implicit.
EDITED:
Just in case, I'm posting another example - simple emulation of how Play' Action works:
object ImplicitArguments extends App {
case class Request(msg:String)
implicit val request = Request("my request")
case class Result(msg:String)
case class Action(result:Result)
object Action {
def apply(block:Request => Result):Action = {
val result = block(...) // what should be here ??
new Action(result)
}
}
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}
println(action)
}
Implicits don't work like this. There is no magic. They are just (usually) hidden parameters and are therefore resolved when invoking the function.
There are two ways to make your code work.
you can fix the implicit value for all invocations of fun
def fun(block: Int=>String): String = {
block(implicitly[Int])
}
implicitly is a function defined in Predef. Again no magic. Here's it's definition
def implicitly[A](implicit value: A) = value
But this means it will resolve the implicit value when declaring the fun and not for each invocation.
If you want to use different values for different invocations you will need to add the implicit paramter
def fun(block: Int=>String)(implicit value: Int): String = {
block(value)
}
This will now depend on the implicit scope at the call site. And you can easily override it like this
val result = fun{ _.toString }(3)
and result will be "3" because of the explicit 3 at the end. There is, however, no way to magically change the fun from your declaration to fetch values from implicit scope.
I hope you understand implicits better now, they can be a bit tricky to wrap your head around at first.
It seems that for that particular case I asked, the answer might be like this:
That this is not really a good idea to use implicit intValue or implicit request along with implicitly() using only one parameter for the function that accept (anonymous) function.
Why not, because:
Say, if in block(...) in apply() I would use implicitly[Request], then
it does not matter whether I use "implicit request" or not - it will use
request that is defined implicitly somewhere. Even if I would pass my
own request to Action { myOwnRequest =Result }.
For that particular case is better to use currying and two arguments and.. in the second argument - (first)(second) to use implicit
Like this:
def apply(block:Request => Result)(implicit request:Request):Action2
See my little effort around this example/use case here.
But, I don't see any good example so far in regards to how to use implicit by passing the (anonymous) function as argument (my initial question):
fun{ implicit intValue => {intValue.toString}
or that one (updated version):
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}