给定以下方法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
)
答案 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)