我对仿函数的简单理解是它可以通过u.map(f)
映射到具有以下约束的东西: -
f
必须是一个功能f
可以返回任何值,并且允许更改类型map
必须返回相同Functor
的值,即。容器的形状和结构不得改变。 一个例子。
scala> List(1, 2, 3).map(x => s"$x")
res8: List[String] = List(1, 2, 3)
我的问题: -
StringOps
将隐式包装java.lang.String
以使用索引序列的常用操作对其进行扩展 - 例如map
。
但以下让我感到困惑。
scala> "Tera".map(x => s"$x").map(x => s"$x")
res12: scala.collection.immutable.IndexedSeq[String] = Vector(T, e, r, a)
我认为map
只返回scala.Predef.String
而不是IndexedSeq[String]
,因为仿函数的定义是它的形状/结构应该保留相同。
这仍然符合仿函数的定义,因为scala.Predef.String
IS-A IndexedSeq[String]
?
答案 0 :(得分:2)
不,String
不是仿函数,正是因为它只能包含Char
。
这是否仍然符合仿函数的定义,因为scala.Predef.String IS-A IndexedSeq [String]?
它不是(它不是IndexedSeq
任何东西,它只能隐式转换为IndexedSeq[Char]
),而它不会。
答案 1 :(得分:1)
我认为地图只会返回
scala.Predef.String
而不是IndexedSeq[String]
,因为算子的定义是这样的 它的形状/结构应该保持不变。
并非所有具有map
方法的类型都遵守Monad的规则。 Scala中的String
不包含monad所需的属性。它不是endofunctor,并且不支持自然转换({3}}(Scala中为flatten
)和join
(apply
))。< / p>
由于您可以定义与monad无关的map
操作,因此monad的以下规则不成立。您可以在字符串上map
返回每个字符的基础整数值:
scala> val s = "hello"
s: String = hello
scala> s.map(_.toInt)
res4: scala.collection.immutable.IndexedSeq[Int] = Vector(104, 101, 108, 108, 111)
此外,IndexedSeq[String]
不是String
。您正在做的是映射String
的每个字符并将其转换为String
。这就是为什么你得到一系列字符串作为回报。您可以将String
视为IndexedSeq[Char]
,但绝对不能IndexedSeq[String]
。