scala - 类型参数子句中的广义约束?

标签 scala type-parameter type-constraints kind-projector

SLS 指定 type parameter clause 的语法作为

TypeParamClause   ::=  ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’
FunTypeParamClause::=  ‘[’ TypeParam {‘,’ TypeParam} ‘]’
VariantTypeParam  ::=  {Annotation} [‘+’ | ‘-’] TypeParam
TypeParam         ::=  (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type}                  {‘<%’ Type} {‘<%’ Type}

我们在哪里看到 >: , <: , <% , <% , :作为类型参数子句中允许的保留名称。有没有办法我们可以使用 generalised type constraint符号名称 <:< , =:=在类型参数子句中这样

def f[T =:= 42] = ???

会扩展到

def f[T](implicit ev: T =:= 42) = ???

类似于上下文绑定(bind)的方式

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

所以,是的,这似乎是可能的。您只需使用 kind projectors 来应用第二个参数。

<:<应该是同一个故事:

@ 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

关于scala - 类型参数子句中的广义约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61045368/

相关文章:

scala - 哪些情况下 Seq.reduce 会采用 A 的父类(super class)型(B)作为参数?

c# - 泛型类型的泛型类型约束

c# - 我可以在要创建的对象的类对泛型类型参数有约束的泛型类中创建泛型对象吗?

Scala:如何使用类型集合?

java - Scala:在类中找不到主要方法

scala - 为什么reduceLeft的类型参数包含下界?

c# - 我什么时候应该或不应该使用泛型类型约束?

java - 将 Scala Future 转化为 CompletableFuture

scala - 如何为多个 Scala 版本和差异依赖项组织代码

java - 方法类型参数出现意外语法错误