Scala如何让Scala提交到指定的类型边界
我创建了一个类型的层次结构,Scala如何让Scala提交到指定的类型边界,scala,types,Scala,Types,我创建了一个类型的层次结构,S_3您可以使用隐式+逆变来执行“大于/小于或等于”: trait _4 trait _3 extends _4 trait _2 extends _3 trait _1 extends _2 trait _0 extends _1 trait >:>[A, -B] //more-than or equals object Laws { implicit def mte[A] = new >:>[A,A]{}//00, 11, 22,
S_3您可以使用隐式+逆变来执行“大于/小于或等于”:
trait _4
trait _3 extends _4
trait _2 extends _3
trait _1 extends _2
trait _0 extends _1
trait >:>[A, -B] //more-than or equals
object Laws {
implicit def mte[A] = new >:>[A,A]{}//00, 11, 22, 33...contravariance will also add 23, 24, 34 etc.
}
import Laws._
//the type here is going to be bound (inclusive) between 3 and 2
def a[T <: _3](a: T)(implicit ev: T >:> _2) = a
trait\u 4
特质3延伸到特质4
特质2延伸到特质3
特质1延伸到特质2
特质_0扩展_1
特征>:>[A,-B]//大于或等于
客观规律{
隐式def mte[A]=new>:>[A,A]{}//00,11,22,33…逆变还将添加23,24,34等。
}
进口法_
//这里的类型将绑定(包括)在3和2之间
定义a[T:>_2)=a
结果:
scala> a(new _2{})
res29: _2 = $anon$1@13a37e2a
scala> a(new _3{})
res26: _3 = $anon$1@779dfe55
scala> a(new _4{})
<console>:27: error: inferred type arguments [_4] do not conform to method a's type parameter bounds [T <: _3]
a(new _4{})
^
<console>:27: error: type mismatch;
found : _4
required: T
a(new _4{})
^
<console>:27: error: could not find implicit value for parameter ev: >:>[T,_2]
a(new _4{})
^
scala> a(new _1{})
<console>:27: error: could not find implicit value for parameter ev: >:>[_1,_2]
a(new _1{})
^
scala>a(新的{})
res29:_2=$anon$1@13a37e2a
scala>a(新的{u3})
res26:_3=$anon$1@779dfe55
scala>a(新的{U 4})
:27:错误:推断的类型参数[_4]不符合方法a的类型参数界限[T:>[T,_2]
a(新{4})
^
scala>a(新的{u 1})
:27:错误:找不到参数ev:>:>[\u 1,\u 2]的隐式值
a(新{1})
^
或者,您可以使用Shapeless:
更新:
以下是针对相反类型层次结构执行此操作的方法:
trait _0
trait _1 extends _0
trait _2 extends _1
trait _3 extends _2
trait _4 extends _3
trait _5 extends _4
import annotation.implicitNotFound
@implicitNotFound("Can’t prove ${A} <= ${B}")
trait <=[A, -B] //less-than or equals
object Laws {
@implicitNotFound("Can’t prove ${A} >= ${B}")
type >=[A,B] = <:<[A,B]
implicit def lte[A] = new <=[A,A]{}//00, 11, 22, 33...contravariance will also add 23, 24, 34 etc.
}
import Laws._
def a[T](a: T)(implicit ev1: T >= _2, ev2: T <= _3) = a
trait\u 0
特征1扩展了特征0
特质2扩展1
特质3延伸2
特质4延伸到特质3
特质5延伸4
import annotation.implicitNotFound
@implicitNotFound(“无法证明${A}=${B}”)
type>=[A,B]=也许,使用无形状的Nat
type:@dk14确实有效,但我想知道是否有办法迫使类型推断更具体。如果type是手动指定的B[s_3](_3)
编译器正确地拒绝了该语句。有时,你不想为了一个特性而引入整个库。这是一个巧妙的技巧。MTE几乎具有与Leib相同的类型,但由于子类型,它将允许类型推断的作用大于或等于。谢谢!唯一遗憾的是,该类型是有效的ely closed.我们不能比_4更高的数字,但为此我最好还是输入编码的自然数。@EdgarKlerks我们实际上可以看到我的更新。Noice,不是吗?顺便说一句,Leibniz
-像[+A,-B]
(在A
上有额外的协方差)也可以工作
object Main extends App {
sealed trait Selector {
def unapply() : Int
}
sealed class S_0 extends Selector {
def unapply() : Int = 0
}
sealed class S_1 extends S_0 {
override def unapply() : Int = 1
}
sealed class S_2 extends S_1 {
override def unapply() : Int = 2
}
sealed class S_3 extends S_2 {
override def unapply() : Int = 3
}
def _0 = new S_0
def _1 = new S_1
def _2 = new S_2
def _3 = new S_3
implicit class Bla2[+A,+B](val x : (A,B)) {
def apply[N >: S_2 <: S_1](i : N) : Any = {
i match {
case 1 => x._1
case 2 => x._2
}
}
}
println("hello world")
val b = (1,2)
b[S_1](_1)
b[S_2](_2)
// this won't compile
// b[S_3](_3)
// but this will
b(_3)
}
trait _4
trait _3 extends _4
trait _2 extends _3
trait _1 extends _2
trait _0 extends _1
trait >:>[A, -B] //more-than or equals
object Laws {
implicit def mte[A] = new >:>[A,A]{}//00, 11, 22, 33...contravariance will also add 23, 24, 34 etc.
}
import Laws._
//the type here is going to be bound (inclusive) between 3 and 2
def a[T <: _3](a: T)(implicit ev: T >:> _2) = a
scala> a(new _2{})
res29: _2 = $anon$1@13a37e2a
scala> a(new _3{})
res26: _3 = $anon$1@779dfe55
scala> a(new _4{})
<console>:27: error: inferred type arguments [_4] do not conform to method a's type parameter bounds [T <: _3]
a(new _4{})
^
<console>:27: error: type mismatch;
found : _4
required: T
a(new _4{})
^
<console>:27: error: could not find implicit value for parameter ev: >:>[T,_2]
a(new _4{})
^
scala> a(new _1{})
<console>:27: error: could not find implicit value for parameter ev: >:>[_1,_2]
a(new _1{})
^
trait _0
trait _1 extends _0
trait _2 extends _1
trait _3 extends _2
trait _4 extends _3
trait _5 extends _4
import annotation.implicitNotFound
@implicitNotFound("Can’t prove ${A} <= ${B}")
trait <=[A, -B] //less-than or equals
object Laws {
@implicitNotFound("Can’t prove ${A} >= ${B}")
type >=[A,B] = <:<[A,B]
implicit def lte[A] = new <=[A,A]{}//00, 11, 22, 33...contravariance will also add 23, 24, 34 etc.
}
import Laws._
def a[T](a: T)(implicit ev1: T >= _2, ev2: T <= _3) = a