我知道我可以定义一个函数def foo(): Int => String
,它返回一个接受整数并返回一个字符串的函数。但是,我希望返回一个稍微复杂的函数,包括泛型和含义。换句话说,我希望能够说出类似def foo(): [T](T)(implicit T) => T
的内容。理想情况下,对于泛型,我宁愿不必使用类型参数foo
定义def foo[T]
- 我希望仅在调用从foo
返回的函数时确定T.
答案 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稍后在呼叫站点处被选择,这更符合您的要求。希望我的回答提供更多细节。