函数文字可以在Scala中使用类型参数吗?

时间:2013-11-29 22:39:27

标签: scala

给定以下方法removeAt的多态性定义:

def removeAt[T](n: Int, ts: Seq[T]): (Seq[T], T) = ???

如何声明类似removeAt的函数列表?函数文字可以使用类型参数吗?

如何使以下内容可编辑并能够包含removeAt

List[(Int, Seq[_]) => (Seq[_], _)](removeAt)

更新:为什么以下工作正常,所以我可以foreach超过列表并执行功能?这正是我首先需要的。

val solutions = Seq[(Int, Seq[Any]) => (Seq[Any], Any)](
  removeAt
)

5 个答案:

答案 0 :(得分:5)

博文First-class polymorphic function values in shapeless (1 of 3) — Function values in Scala似乎意味着“标准”Scala无法获得多态函数值:

  

我们可以拥有一流的单态函数值   二等多态方法,但我们不能拥有一流的   多态函数值...至少我们不能用标准   Scala定义。

看起来我们需要像shapeless这样的库。

答案 1 :(得分:0)

足以让容器携带这些功能的是使用底部类型,例如:

val f = removeAt _ 

var l: List[(Int, Seq[Nothing]) => (Seq[Nothing], Nothing)] = Nil
l = f :: l

我已在本文中解释过它们,例如:http://ktoso.github.io/scala-types-of-types/#the-bottom-types-nothing-and-null

答案 2 :(得分:0)

你可能会问一些比这更通用的东西,但对于上述问题,我觉得你只是接近它错了。如果我是你,我会使用隐式value class 扩展Seq以支持removeAt方法。这是一个添加removeAt方法的示例:

implicit class MoreSeqOps[T](val seq: Seq[T]) extends AnyVal {
  def removeAt(n: Int): (Seq[T], T) = {
    val (xs, ys) = seq.splitAt(n)
    return (xs ++ ys.tail, ys.head)
  }
}

通过使用值类,可以避免与创建包装器实例相关的额外开销。以下是REPL的示例用法:

scala> (1 to 10) removeAt 3
res7: (Seq[Int], Int) = (Vector(1, 2, 3, 5, 6, 7, 8, 9, 10),4)

答案 3 :(得分:0)

好的,所以我们有一个多态函数(只有尝试和编译的例子,使用无形):

def removeAt[T](n: Int, ts: Seq[T]): (Seq[T], T) = ...

让我们定义这些函数的HList

val mapList = 
    removeAt[Int] _     ::
    removeAt[String] _  ::
    removeAt[Boolean] _ :: HNil

因此,可以采用任何这些功能并应用它。

由于更新后的示例:事实上,您丢失了有关多态函数类型的所有信息(由于类型擦除)。列表中的所有功能都会有(Int, Seq[Any]) => (Seq[Any], Any)类型,但我认识并不好。

所以使用常见列表,你可以做同样的事情(你应该写类型参数),但是,你将失去关于函数类型的所有信息,事实上,制作这样的列表或seq是没有意义的。

答案 4 :(得分:0)

这对你有帮助吗?

val removeAt: Int => Seq[_] => (Seq[_], _) = n => seq => (seq, seq(n))

val listOfRemoveFun = List[(Int => Seq[_] => (Seq[_], _))](removeAt)

listOfRemoveFun.foreach(fun => println(fun(1)(Seq(1,2,3))))   //(List(1, 2, 3),2)