Scala:带有列表和选项的函数中的无名参数

标签 scala function scala-cats

2个不同的例子,第一个有效:

  import cats.syntax.either._
  val e = 10.asRight[String]
  def i2s(i:Int):String = i.toString
  e.map(i => List(i2s(i))) //using explicit parameter
  e.map(List(i2s(_)))   //using no-name _ parameter

现在没有编译带有 Option 的相同示例:
e.map(Option(i2s(_))) 

错误:
Error:(27, 15) type mismatch;
 found   : Option[Int => String]
 required: Int => ?
  e.map(Option(i2s(_)))

使用显式参数它工作正常:
e.map(i => Option(i2s(i)))

在这两种情况下,apply 方法都是用 List 和 Option 调用的。 List.apply签名:
 def apply[A](xs: A*): List[A] = ???
Option.apply签名:
 def apply[A](x: A): Option[A]

请解释区别。

最佳答案

您的List示例可以编译,但它们的意思不同,也不会产生相同的结果。

e.map(i => List(i2s(i))) //res0: scala.util.Either[String,List[String]] = Right(List(10))
e.map(List(i2s(_)))      //java.lang.IndexOutOfBoundsException: 10

第一个很容易理解,那么第二个呢?

发生的事情是您正在使用 eta expansion创建一个 Int => String来自 i2s() 的函数方法。然后填充 List将该单个函数作为列表中的唯一元素,然后尝试检索索引 10 处的值,它不存在,因此是异常(exception)。

如果将第一行更改为 val e = 0.asRight[String]然后异常消失,因为索引 0 中确实存在某些内容,刚才放在那里的函数。

这编译是因为 List实例将接受 Int作为参数(通过隐藏的 apply() 方法),但是一个 Option实例没有 apply()采用 Int 的方法(*) 所以无法编译。

(*) Option对象确实有一个 apply()方法,但那是另一种动物。

关于Scala:带有列表和选项的函数中的无名参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56250926/

相关文章:

scala - 将列表项映射到 org.apache.spark.sql.Column 类型

使用 void 指针连接两个数组 (C)

scala - 如何推理 Scala Cats/fs2 中的堆栈安全?

scala - 如果使用 cats IO 选项为 None,如何停止 for-compression 的执行?

scala - Scala-Spark 开发人员是否必须在他的计算机上安装 Spark 和 Hadoop?

scala - 使用 Argonaut Lenses 从 JSON 对象的 JSON 数组中提取值

python - python中函数的参数命名约定

python - 如何返回false而不是断言错误?

scala - 猫效应: Avoid calling unsafeRun on external listener of T => Unit

scala - 类型不匹配;找到 : Long required: Int