将参数函数指定为输入,而不会在Scala中过度约束它们

时间:2017-10-20 16:42:37

标签: scala types polymorphism

在设计更高阶的类型界面时,我已经支持自己进入了一个有趣的角落。

我想做这样的事情

trait SomeTrait {
  def higherOrder(f: (Int, A) => List[A]): String
}

object SomeImple extends SomeTrait {
  def higherOrder(f: (Int, A) => List[A]): String = {
    f(3, "HI").mkString(", ") + f(3, 7).mkString(", ")
  }
}

我想指定一个函数将另一个更高阶函数作为适用于任何类型的输入(在本例中为A)。例如:

def someFun[A](n: Int, a: A): List[A] =
  if (n <= 0) {
    List.empty
  } else {
    a :: (someFun(n - 1, a))
  }

但是,如果向higherOrder添加类型参数,则意味着函数f只能在一种类型中使用。有没有办法将参数函数作为输入而不过度约束它们?

2 个答案:

答案 0 :(得分:1)

您无法对此类函数进行参数化,但您可以参数化方法:

trait SomeTrait {
  def higherOrder(fn: {def apply[A](n: Int, a: A): List[A]}): String
}

object SomeImple extends SomeTrait {
  def higherOrder(f: {def apply[A](n: Int, a: A): List[A]}): String = {
    f(3, "HI").mkString(", ") + f(3, 7).mkString(", ")
  }
}

object someFun {
  def apply [A] (n: Int, a: A): List[A] = {
    if (n <= 0) {
      List.empty
    } else {
      a :: (someFun(n - 1, a))
    }
  }
}

使用结构类型(或者您可以创建可以通过持有方法的类型实现的特征),您可以请求该方法采用类型参数。

不幸的是,你必须将它包装在一个对象(或某个类)中,因为常规方法只能被提升&#34; FunctionFunction类型参数在定义时固定。

供参考:https://gist.github.com/jdegoes/97459c0045f373f4eaf126998d8f65dc#polymorphic-functions

答案 1 :(得分:0)

将类型传递给您的函数有什么问题? Solution

_v[20] = std::make_unique<item>(/* Args */);