Let's say I have some code that uses List
def processList(input: List[Int]): List[Int]
I want to replace list with other collection types, like Vector.
Is there a way to define a type constructor so that I can write something like
type SomeCollection[_] = List[_]
def processList(input: SomeCollection[Int]): SomeCollection[Int]
Now I have written processList in terms of SomeCollection. To change SomeCollection to Vector, I just change the type alias, and everywhere in the codebase where I use SomeCollection, I now use Vector. Like so:
type SomeCollection[_] = Vector[_]
def processList(input: SomeCollection[Int]): SomeCollection[Int]
This way, I only need to change the codebase in one place instead of everywhere.
I do not want to write
type SomeIntCollection = List[Int]
because I have connected the collection to Int type.
Is there a way?
You're pretty close, this can be done along the lines of
type SomeCollection[A] = List[A]
def processList(input: SomeCollection[Int]): SomeCollection[Int] = input.map(_+1)
However, there's better ways to describe the abstraction. In the cats
library, there are a variety of typeclasses designed to abstract over the type of operation you want to perform. The above with cats would look something like
import cats._
import cats.implicits._
def process[F[_]: Functor](input: F[Int]): F[Int] = input.map(_+1)
It doesn't lock you into a specific underlying collection, so you're free to use whatever makes the most sense at the call site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With