String + StringOps = functor?

时间:2016-10-21 08:41:33

标签: scala functional-programming

我对仿函数的简单理解是它可以通过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]

2 个答案:

答案 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)和joinapply))。< / 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]