类型参数子句中的广义约束?
Generalized constraints within type parameter clause?
SLS 将 type parameter clause 的语法指定为
TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’
FunTypeParamClause::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’
VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam
TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type} {‘<%’ Type} {‘<%’ Type}
我们在类型参数子句中看到 >:
、<:
、<%
、<%
、:
作为允许的保留名称。有没有一种方法可以在类型参数子句中使用 符号名称 <:<
、=:=
这样
def f[T =:= 42] = ???
会扩展到
def f[T](implicit ev: T =:= 42) = ???
类似于上下文绑定的方式
def f[T: Numeric] = ???
扩展到
def f[T](implicit ev: Numeric[T]) = ???
在 2.13 中(它支持单例类型,如果你对单例的约束感到好奇的话)你可以做这样的事情:
@ import $plugin.$ivy.`org.typelevel:kind-projector_2.13.1:0.11.0`
import $plugin.
@ type a = 23
defined type a
@ def f[N : * =:= a]: Unit = ()
defined function f
@ f[a]
@ f[23]
@ f[25]
cmd9.sc:1: Cannot prove that 25 =:= Int(23).
val res9 = f[25]
^
Compilation Failed
@ def g[N : * =:= 16]: Unit = ()
defined function g
@ g[16]
@ g[23]
cmd11.sc:1: Cannot prove that 23 =:= 16.
val res11 = g[23]
^
Compilation Failed
所以,是的,这似乎是可能的。你只需要使用种类投影仪来应用第二个参数。
与<:<
应该是同一个故事:
@ def h[N : * <:< 16]: Unit = ()
defined function h
@ h[16]
@ h[17]
cmd13.sc:1: Cannot prove that 17 <:< 16.
val res13 = h[17]
^
Compilation Failed
SLS 将 type parameter clause 的语法指定为
TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’
FunTypeParamClause::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’
VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam
TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type} {‘<%’ Type} {‘<%’ Type}
我们在类型参数子句中看到 >:
、<:
、<%
、<%
、:
作为允许的保留名称。有没有一种方法可以在类型参数子句中使用 <:<
、=:=
这样
def f[T =:= 42] = ???
会扩展到
def f[T](implicit ev: T =:= 42) = ???
类似于上下文绑定的方式
def f[T: Numeric] = ???
扩展到
def f[T](implicit ev: Numeric[T]) = ???
在 2.13 中(它支持单例类型,如果你对单例的约束感到好奇的话)你可以做这样的事情:
@ import $plugin.$ivy.`org.typelevel:kind-projector_2.13.1:0.11.0`
import $plugin.
@ type a = 23
defined type a
@ def f[N : * =:= a]: Unit = ()
defined function f
@ f[a]
@ f[23]
@ f[25]
cmd9.sc:1: Cannot prove that 25 =:= Int(23).
val res9 = f[25]
^
Compilation Failed
@ def g[N : * =:= 16]: Unit = ()
defined function g
@ g[16]
@ g[23]
cmd11.sc:1: Cannot prove that 23 =:= 16.
val res11 = g[23]
^
Compilation Failed
所以,是的,这似乎是可能的。你只需要使用种类投影仪来应用第二个参数。
与<:<
应该是同一个故事:
@ def h[N : * <:< 16]: Unit = ()
defined function h
@ h[16]
@ h[17]
cmd13.sc:1: Cannot prove that 17 <:< 16.
val res13 = h[17]
^
Compilation Failed