I have the following trait:
import scalaz.Monoid
trait Mapper[M, R] {
def map(m: M): R
}
object Mapper {
@inline implicit def listMapper[M, R]
(implicit mapper: Mapper[M, R], s: Monoid[R]): Mapper[List[M], R] =
(xs: List[M]) => xs. foldLeft(s.zero)((r, m) => s.append(r, mapper.map(m)))
}
Now I want to list mapper for with R = String
that produces something like the following [mapped_string1, mapped_string2]
or
$%%""mapped_string1, mapped_string2""%%$
.
The question is the following monoid implementation will not work:
implicit val myStringMonoid: Monoid[String] = new Monoid[String] {
override def zero = ""
override def append(f1: String, f2: => String) =
if (f1.isEmpty) f2
else if(f2.isEmpty) f1
else f1 + ", " + f2
}
So the following line
println(implicitly[Mapper[List[String], String]].map(List("mapped_string1", "mapped_string2")))
prints mapped_string1, mapped_string2
without angle brackets.
What would be a solution for that case? Maybe just monoids does quite fit my needs. Maybe I need another level of abstraction.
I mean how to generally add some additional operation to be invoked after foldLeft
is finished? Without coupling to String
or any particular type.