我有以下特点:
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)))
}
现在我想列出mapper for R = String
,它会产生类似以下[mapped_string1, mapped_string2]
或类似内容的内容
$%%""mapped_string1, mapped_string2""%%$
。
问题是以下幺半群实现不起作用:
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
}
以下一行
println(implicitly[Mapper[List[String], String]].map(List("mapped_string1", "mapped_string2")))
打印mapped_string1, mapped_string2
,不带尖括号 。
这种情况的解决方案是什么?也许只是monoids确实非常符合我的需求。也许我需要另一层次的抽象。
我的意思是如何在foldLeft
完成后通常添加一些额外的操作来调用?没有耦合到String
或任何特定类型。
答案 0 :(得分:2)
package.json
表示如果您拥有implicit def listMapper[M, R]
(implicit mapper: Mapper[M, R], s: Monoid[R]): Mapper[List[M], R] = ???
,则表示您拥有Mapper[M, R]
。但为了完成这项工作,您应该有一些初始Mapper[List[M], R]
。
因此,如果你想要Mapper[M, R]
,你应该添加例如
Mapper[List[String], String]
然后生成
implicit def stringMapper: Mapper[String, String] = s => s
否则你可以改变
println(implicitly[Mapper[List[String], String]].map(List("mapped_string1", "mapped_string2")))
//mapped_string1, mapped_string2
def addBrackets(s: String, openBracket: String, closingBracket: String) =
openBracket + s + closingBracket
val s = implicitly[Mapper[List[String], String]].map(List("mapped_string1", "mapped_string2"))
println(addBrackets(s, "[", "]"))
//[mapped_string1, mapped_string2]
然后
implicit val myStringMonoid: Monoid[String] = new Monoid[String] {
override def zero = ""
override def append(f1: String, f2: => String): String =
if (f1.isEmpty) f2
else if(f2.isEmpty) f1
else f1 + f2 // without ", "
}