Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何创建在数组和选项上通用的函数_Scala - Fatal编程技术网

Scala 如何创建在数组和选项上通用的函数

Scala 如何创建在数组和选项上通用的函数,scala,Scala,我想创建一个通用函数,作为一个选项同时适用于数组: val numbers = Array(1, 2, 3) val numberO: Option[Int] = Some(4) def addOnes(numbers: ???[Int]) = numbers.map(_+1) addOnes(numbers) addOnes(numberO) 现在每个结构都有一个单独的函数 def addOnesForArray(numbers: Array[Int]) = numbers.map(_+

我想创建一个通用函数,作为一个选项同时适用于数组:

val numbers = Array(1, 2, 3)
val numberO: Option[Int] = Some(4)

def addOnes(numbers: ???[Int]) = numbers.map(_+1)

addOnes(numbers)
addOnes(numberO)
现在每个结构都有一个单独的函数

def addOnesForArray(numbers: Array[Int]) = numbers.map(_+1)
def addOnesForOption(numberO: Option[Int]) = numberO.map(_+1)

addOnesForArray(numbers)
addOnesForOption(numberO)

所以基本上我需要一个数组和选项的超类,它有函子和单子方法map,flatMap,filter,

你可以使用结构类型,也就是duck类型,我们可以说你需要一个映射,写为{def map:T}。但这是一个丑陋的例子,b使用反射,c注意map:T只是一个例子;事实上,你必须匹配地图的精确签名,以及CanBuildFrom和所有的爵士乐

更好的方法是接触或使用范畴理论概念。只需选择功能最不强大的抽象即可。如果你只需要映射,那么它就是一个函子。如果您想映射多个参数的curried函数,那么它是一个应用程序。如果你也想要平面图,那么它是单子,等等

函子示例:

import scalaz._, Scalaz._

def addOne[F[Int]](f: F[Int])(implicit m: Functor[F]) = f.map(_ + 1)

val numbers = Array(1, 2, 3).toList
val numberO = Option(123)

addOne(numbers) // List(2, 3, 4)
addOne(numberO) // Some(124)

您会注意到,我必须将数组转换为列表,因为据我所知,在数组上没有函子、应用程序、单子等的类型类实例。但是数组是老式的、不变的,而且实际上并不是惯用的Scala。如果您从其他地方获得它们,只需根据您的用例将它们转换为列表、向量等,并从那时起使用它们。

一般来说,我同意@slouc。如果你想让现有的类扩展一些其他特性,你需要类型类。 但在您的特定情况下,它不是必需的,因为选项和数组都是可遍历的:


这是否适用于这两个或任何具有贴图、平面贴图等的对象?您是否尝试过提供函子实例的库猫、scalaz?Hi-Assaf理想情况下越通用越好,尽管目前我只需要数组和选项的解决方案Hi-Yuval,不,我还没有尝试过,我希望尽可能远离scala advanced;-但是,如果这是我可能选择的唯一解决方案,我同意这一点,如果他的用例是我需要一些可遍历的。但他说我需要函子和单子方法。如果他想描绘未来呢?事实上,理想情况下,解决方案应该适用于任何函子和单子,但如果这意味着引入scalaz,我只喜欢集合式结构。事实上,Traversable是数组和选项的常见超类。知道如何保持输出集合与输入集合相同吗?我尝试使用def plus2[F x+2],但似乎没有compile@NiekBartholomeus如果您需要保留输出集合的类型,请使用slouc提供的解决方案,不要重新发明轮子。
object Example extends App {
  def plus1(data: Traversable[Int]): Traversable[Int] = data.map(x => x + 1)

  println(plus1(Array(1, 2, 3)))
  println(plus1(Some(4)))
}