Nio Nio - 1 month ago 13
Scala Question

String + StringOps = functor?

My simple understanding of a functor is that it is just something that can be mapped over

u.map(f)
with the following constraints:-


  • f
    must be a function

  • f
    can return any value and the type is allowed to change

  • map
    must return a value of the same
    Functor
    ie. the shape and structure of the container must not change.



And an example.

scala> List(1, 2, 3).map(x => s"$x")
res8: List[String] = List(1, 2, 3)


My question:-

StringOps
will implicitly wrap a
java.lang.String
to extend it with operations common to indexed sequences - such as
map
.

But the following confuses me a bit.

scala> "Tera".map(x => s"$x").map(x => s"$x")
res12: scala.collection.immutable.IndexedSeq[String] = Vector(T, e, r, a)


I assumed that
map
would return me just a
scala.Predef.String
rather than an
IndexedSeq[String]
since the definition of a functor is that it's shape/structure should remain the same.

Does this still meet the definition of a functor because
scala.Predef.String
IS-A
IndexedSeq[String]
?

Answer

I assumed that map would return me just a scala.Predef.String rather than an IndexedSeq[String] since the definition of a functor is that it's shape/structure should remain the same.

Not every type that has a map method adheres to the rules of Monad. A String in Scala does not hold the properties required from a monad. It isn't an endofunctor, and it doesn't hold natural transformations (join (flatten in Scala) and return(apply)).

As you can define map operations which are unrelated to monads, the following rules of the monad don't hold. You can map over a string to return the underlying integer values of each of it's characters:

scala> val s = "hello"
s: String = hello

scala> s.map(_.toInt)
res4: scala.collection.immutable.IndexedSeq[Int] = Vector(104, 101, 108, 108, 111)

Further, an IndexedSeq[String] is not a String. What you're doing is mapping over every character of the String and converting it into a String. That is why you get a sequence of strings in return. You can view a String as an IndexedSeq[Char], definitely not as an IndexedSeq[String] though.