Search code examples
listscaladictionary

Scala - List("a","b").map(fn) versus map(fn, List("a","b")


From Scala's site, there is an example of reimplementing method map for List, and the usage of it is as below

Case 1

def strlen(s: String): Int = s.length
map(strlen, List("a", "bb", "ccc"))   // List(1, 2, 3)

From native support of scala, calling map on List would be as below:

Case 1

List("a","b").map(x => x.length)

How to write map that could be called like the native way?

Specifically, I want to clarify about this: within the example of scala (Case 1), the implementation utilize Functor. But, from source code on github of scala, the implemention does not utilize Functor.


Solution

  • You can look into type classes. Check the example for Show type class, representing "anything that can be shown". It's the same in your case, except you want "anything that can be mapped". You would then implement a type class instance for your desired type (in your example List) and provide it using the implicit/given mechanism (depending on Scala 2 vs Scala 3).

    Functor is a functional programming construct coming from category theory, and in simple and concrete terms, it's exactly that - a representation of "something that can be mapped". It is usually found in functional programming Scala libraries such as Cats, Zio, ex-twitter's Algebrid etc, and it is implemented via described type class mechanism. There are many kinds of collections that can implement the Functor type class - most collections (such as List), but also e.g. Option, even effect types such as Future / IO / Task etc.

    However, native Scala doesn't use the Functor approach; it simply implements map directly in the collections hierarchy, which in case of List would be in Traversable (iirc).

    Of course, it doesn't make sense to add (another) map to a List, but I'm assuming you're asking for learning purposes. You could practice by adding another map-like method to List (e.g. myMap). In that case you can define your own type class (e.g. Mappable) and provide an instance/implementation of that type class for List. Another interesting practice would be to define a custom collection (e.g. MyList) and write a Functor instance for it, so that you can do myList.map(someFunction).