返回具有泛型和含义的函数的函数签名?

时间:2014-06-13 16:46:51

标签: scala generics implicit

我知道我可以定义一个函数def foo(): Int => String,它返回一个接受整数并返回一个字符串的函数。但是,我希望返回一个稍微复杂的函数,包括泛型和含义。换句话说,我希望能够说出类似def foo(): [T](T)(implicit T) => T的内容。理想情况下,对于泛型,我宁愿不必使用类型参数foo定义def foo[T] - 我希望仅在调用从foo返回的函数时确定T.

2 个答案:

答案 0 :(得分:1)

正如Miles Sabin在his blog post on first-class polymorphic function values中更详细地解释(并且更加雄辩),你的目标可以通过一些努力来实现。 “值不能是通用的”在Scala的内置函数值方面是正确的,但类似函数的对象可以定义通用apply方法(因此充当呼叫网站的通用功能):

class Foo {
  def apply[T, E, R](x: T)(implicit e: E): R = ???
}

def foo = new Foo

val fn = foo // fn is effectively a generic function value!

答案 1 :(得分:1)

另一个帮助您上路的链接 http://existentialtype.net/2008/05/26/revisiting-higher-rank-impredicative-polymorphism-in-scala/

trait forall[P[_]] {
  def apply[A]: P[A]
}

trait Nat[F[_], G[_]] {
  def apply[A](x: F[A]): G[A]
}

def foo: forall[({ type λ[τ] = τ => String })#λ] = ???

以上是一些类型可能会帮助您在一般性水平(通用性?)上进行写作。正如上面评论的那样,价值不可能是通用的......"正如Norvstrup先生在上面提到的,在scala函数中,函数并不总是起作用。有时它们是方法和scala语言规范中的某个地方,它详细说明了方法值和函数值之间的关系,方法并不是值类型,但这与某些方面的关系不大。你正试图在上面做。什么特别关键的是你想要做的是命名绑定。我发布的链接以及Novstrup先生的回答中的链接解释了它比我更好的方式,但要点AFAIU就是选择特定类型的时候。在scala std lib中的普通函数类型中,这有点像

trait function[T, R] {
  def apply(x: T): R
}

函数的域和codomain类型在函数的定义中选择,其中as 在诸如forall或Nat(这是一种编码自然变换的方式,但又是另一种时间)的类型中,类型A稍后在呼叫站点处被选择,这更符合您的要求。希望我的回答提供更多细节。