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