Last active
December 16, 2015 00:38
-
-
Save ilguzin/5348750 to your computer and use it in GitHub Desktop.
Implicit conversions to work inside collections. Stolen from http://stackoverflow.com/questions/12447968/how-can-i-get-implicit-conversions-to-work-inside-collections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here are a few alternatives you might wish to consider: | |
1. Use a view bound | |
If it's possible to change the function that takes a List of Bs, this would be the simplest solution. Modify it to accept a List of things that can be converted to Bs. That is, | |
def myfun(l: List[B]) = ... | |
would become | |
def myfun[X <% B](l: List[X]) = ... | |
Then, you can just call the function with listOfA: | |
myfun(listOfA) | |
2. Introduce a conversion method | |
This is similar to Rogach's first solution, except that the outer conversion is non-implicit: | |
def convert[B, A <% B](l: List[A]): List[B] = l map { a => a: B } | |
Then at your function's call-site, you would write | |
yourFn(convert(listOfA)) | |
Like Rogach's second solution, this is bit safer than bringing in an implicit conversion. | |
3. Introduce an implicit conversion | |
This is equivalent to Rogach's first solution, but the notation is a bit nicer (IMO). | |
implicit def convert[B, A <% B](l: List[A]): List[B] = l map { a => a: B } | |
If this conversion is in scope at your call-site, you can just call your function with the listOfA: | |
yourFn(listOfA) | |
Parting Thoughts | |
It's interesting to consider how to solve this problem in a general way. What if I want to define my conversion method so that it can handle any type that implements the map method? i.e., | |
def convert[B, A <% B, C[_]](c: C[A]): C[B] = c map { a => a: B } | |
This won't work, of course, since nothing in the signature expresses the constraint that C must implement map. As far as I know, expressing this constraint is fairly involved and cannot be done in a way that provides out-of-the-box support for any type that implements map. See Type-safe Scala sequence comprehensions. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment