Reputation: 397
So with this code the head
and exists
methods are not returning a Char but a String so i can't use any Char method.
implicit val mapTest: Map[String, Set[String]] = Map(
"foo" -> Set("foo")
)
val stringTest: String = "test"
//This don't compile
stringTest.head.isLetter
stringTest.exists(_.isLetter)
If i remove the implicit, it works fine. It works fine if i change the Map definition to Map[String, String]
, but using any Collection in the map makes is not compile.
Is there a way to make it work? I also tried defining the Char
type after calling head
but it still fails
Upvotes: 1
Views: 39
Reputation: 48420
Implicit conversions may lead to seemingly magical changes to semantics of the code and loss of control by the developer, which your example nicely demonstrates. For this reason they are often discouraged and we are advised to find ways to refactor the code to not use them if at all possible.
If there is no way around it, consider moving the implicit conversion "out-of-scope" by wrapping it in another object like so
object FooImplicits {
implicit def mapTest: Map[String, Set[String]] = Map(
"foo" -> Set("foo")
)
}
and then try to avoid importing them at the top level, but instead import FooImplicits._
only where it is absolutely necessary.
Note that implicits are acceptable when defining typeclasses and extension methods.
Upvotes: 1
Reputation: 9168
Don't expose mapTest
in implicit scope: as it offers .apply(key: String): Set[String]
it's considered as an implicit conversion String => Set[String]
.
Anyway implicit conversion should be defined/used with caution, due to readability drawbacks.
Using
.head
(or.get
) is a code smell.
Upvotes: 2