在Scala中使用变量类型指定或实现类型类

在Scala中使用变量类型指定或实现类型类,scala,variant,Scala,Variant,我是Scala新手,需要一些帮助来解决编译错误: [error] .../traversals /traversals.scala:120: type mismatch; [error] found : Traversable[Tree] [error] required: Traversable[Node] [error] Note: Tree >: Node, but trait Traversable is invariant in type T. [error] You

我是Scala新手,需要一些帮助来解决编译错误:

[error] .../traversals  /traversals.scala:120: type mismatch;
[error]  found   : Traversable[Tree]
[error]  required: Traversable[Node]
[error] Note: Tree >: Node, but trait Traversable is invariant in type T.
[error] You may wish to define T as -T instead. (SLS 4.5)
[error]             println ("Sorted " + sorted (tree2) (monadApp,inOrder));
[error]                                                           ^
[error] one error found
很抱歉,MWE太长了,但我以一种朴素的方式将一些类型类从Haskell翻译成Scala,并且在编写一些使用它们的示例时遇到了困难。 我不完全理解这个问题,但似乎我的
可遍历
特性不允许将
t
替换为某个子类型,或者使用实例的具体实例
inOrder
或函数
sorted
。根据编译器的建议,我尝试在
可遍历的
特征的
T
前面添加一些
-
s,在
顺序定义前面添加
树,或者在
排序的
前面添加
T
,但没有帮助

 trait Applicative[M[_]] {
    def pure[a] (x: a) : M[a]
    def comp[a,b] (fx: M[a => b]) (mx: M[a]) : M[b]
    def fmap[a,b] (fx: a => b) (mx: M[a]) : M[b]
        = comp (pure (fx)) (mx)
  }

  trait Functor[F[_]] {
    def fmap[a,b] (f: a => b) (m: F[a]) : F[b]   
  }

  trait Traversable[T[_]] extends Functor[T] {
    def dist[a,M[_]] (t: T[M[a]]) (implicit app : Applicative[M]) : M[T[a]]
    def traverse[a,b,M[_]] (f: a => M[b]) (t : T[a]) (implicit app : Applicative[M]) : M[T[b]] = 
    dist (fmap(f) (t)) (app)
  }

  sealed abstract class Tree[a]
  case class Empty[a] () extends Tree[a]
  case class Node[a]  (x : a, l : Tree[a], r: Tree[a]) extends Tree[a]

  class TreeFunctor extends Functor[Tree] {
    def fmap[a,b] (f: a => b) (t: Tree[a]) =
    t match {
        case Empty () => Empty ()
        case Node (x, l, r) => Node (f (x), fmap (f) (l), fmap (f) (r))
    }
  }

  trait Monoid[A] {
    def mempty : A
    def mappend (x: A) (y: A) : A
  }

  object BoolAnd extends Monoid[Boolean] {
    def mempty = true
    def mappend (x: Boolean) (y: Boolean) = x && y    
  }

  case class K[b,a] (value: b) 

  class MonoidApplicative[m] (implicit monoid : Monoid[m]) extends Applicative[({type λ[α] = K[m,α]})#λ] {
    def pure[a] (x : a) = K (monoid.mempty)
    def comp[a,b] (f : K[m,a => b]) (x : K[m,a]) = K (monoid.mappend (f.value) (x.value))
  }

  case class State[s,a] (func: s => (a,s)) 

  trait Monad[M[_]] {
    def ret[a] (x : a) : M[a]
    def bind[a,b] (mx : M[a]) (fx : a => M[b]) : M[b]
  }

  class StateMonad[S] extends Monad[({type λ[α] = State[S,α]})#λ] {
    def ret[a] (x : a) = State ((s: S) => (x, s))
    def bind[a,b] (mx : State[S,a]) (fx : a => State[S,b]) 
      = State ((s : S) => (((tuple : (a,S)) => (fx (tuple._1)).func (tuple._2)) (mx.func (s))))
  }

  class MonadApp[M[_]] (implicit m : Monad[M]) extends Applicative[M] {
    def pure[a] (x : a) = m.ret (x)
    def comp[a,b] (fx : M[a => b]) (mx : M[a]) : M[b] 
      = m.bind[a => b,b] (fx) ((f : a => b) => m.bind[a,b] (mx) ((x:a) => m.ret (f (x))))
  }

  case class Comp[M[_],N[_],a] (unComp : M[N[a]])

  class CompApp[M[_], N[_]]  (implicit mapp : Applicative[M], napp: Applicative[N])  extends Applicative[({type λ[α] = Comp[M,N,α]})#λ] {
    def pure[a] (x : a) = Comp (mapp.pure ( napp.pure ( x) ))
    def comp[a,b] (mf : Comp[M,N,a => b]) (mx : Comp[M,N,a]) = Comp (mapp.comp (mapp.comp (mapp.pure (napp.comp[a,b]_)) (mf.unComp)) (mx.unComp) ) 
  }

  object Main {  
    implicit def inOrder : Traversable[Tree] = new Traversable[Tree]{
        def dist[a,M[+_]] (t: Tree[M[a]]) (implicit app : Applicative[M]) 
        = t match {
            case Empty () => app.pure (Empty ())
            case Node (x, l, r) => app.comp (app.comp (app.comp(app.pure ((l : Tree[a]) => ((x: a) => ((r: Tree[a]) => Node (x,l,r))))) (dist (l) (app))) (x)) (dist (r) (app))
        }
    }   
    val emptyTree = Empty[Int]()
    val tree2 = Node(5, Node (2, Empty (), Empty ()), Node (9 , Empty (), Empty ()))
    implicit def stateMonad[a] = new StateMonad[a] ()
    implicit def monadApp = new MonadApp[({type λ[α] = State[Int,α]})#λ] () {}
    implicit def andMonoidApp  = new MonoidApplicative[Boolean] () (BoolAnd);
    implicit def stateMonoidComp = new CompApp[({type κ[β] = State[Int,β]})#κ, ({type λ[α] = K[Boolean,α]})#λ ] () (monadApp, andMonoidApp)
    def pairSort (x : Int) : State[Int,Boolean] 
        = State ((y : Int) => (y <= x, x))
    def sorted[T[_]] (t : T[Int]) (implicit as : Applicative[({type λ[α] = State[Int,α]})#λ], tr : Traversable[T]) : Boolean
        = (
           (tr.traverse[Int,Boolean,({type λ[α] = Comp[({type κ[β] = State[Int,β]})#κ, ({type λ[α] = K[Boolean,α]})#λ , α]})#λ] 
            ((i : Int) => 
               Comp[({type κ[β] = State[Int,β]})#κ, ({type λ[α] = K[Boolean,α]})#λ , Boolean] 
                 (as.fmap[Boolean, K[Boolean,Boolean]] ((x: Boolean) => K[Boolean, Boolean] (x)) (pairSort (i)))
            )
            (t) 
            //(CompApp[({type κ[β] = State[Int,β]})#κ, ({type λ[α] = K[Boolean,α]})#λ ])
            (stateMonoidComp)
           ).unComp.func (-10000) 
          )._1.value
    def main (args: Array[String]) 
        =   println ("Sorted " + sorted (tree2) (monadApp,inOrder));

  }
trait Applicative[M[\u]]{
def纯[a](x:a):M[a]
def comp[a,b](fx:M[a=>b])(mx:M[a]):M[b]
def fmap[a,b](fx:a=>b)(mx:M[a]):M[b]
=comp(纯(fx))(mx)
}
特征函子[F[]]{
def fmap[a,b](f:a=>b)(m:f[a]):f[b]
}
特征可遍历[T[\u]]扩展函子[T]{
def dist[a,M[]](t:t[M[a]](隐式app:Applicative[M]):M[t[a]]
定义遍历[a,b,M[]](f:a=>M[b])(t:t[a])(隐式app:Applicative[M]):M[t[b]=
区(机动部队指挥官(f)(t))(应用)
}
密封抽象类树[a]
case类Empty[a]()扩展树[a]
案例类节点[a](x:a,l:Tree[a],r:Tree[a])扩展了Tree[a]
类TreeFunctor扩展函子[Tree]{
def-fmap[a,b](f:a=>b)(t:Tree[a])=
不匹配{
大小写为空()=>Empty()
案例节点(x,l,r)=>节点(f(x),fmap(f)(l),fmap(f)(r))
}
}
特征幺半群[A]{
def mempty:A
def mappend(x:A)(y:A):A
}
对象布尔扩展幺半群[布尔]{
def mempty=true
def mappend(x:Boolean)(y:Boolean)=x&&y
}
案例类别K[b,a](值:b)
类MonoidApplicative[m](隐式幺半群:幺半群[m])扩展了Applicative[({typeλ[α]=K[m,α]})#λ]{
def纯[a](x:a)=K(幺半群mempty)
def comp[a,b](f:K[m,a=>b])(x:K[m,a])=K(monoid.mappend(f.value)(x.value))
}
案例类状态[s,a](func:s=>(a,s))
性状单体[M[]]{
def ret[a](x:a):M[a]
def绑定[a,b](mx:M[a])(fx:a=>M[b]):M[b]
}
类StateMonad[S]扩展了Monad[({typeλ[α]=状态[S,α]})#λ]{
def ret[a](x:a)=状态((s:s)=>(x,s))
def绑定[a,b](mx:State[S,a])(fx:a=>State[S,b])
=状态((s:s)=>((tuple:(a,s))=>(fx(tuple.\u 1)).func(tuple.\u 2))(mx.func(s)))
}
类MonadApp[M[]](隐式M:Monad[M])扩展了Applicative[M]{
def纯[a](x:a)=m.ret(x)
def comp[a,b](fx:M[a=>b])(mx:M[a]):M[b]
=m.bind[a=>b,b](fx)((f:a=>b)=>m.bind[a,b](mx)((x:a=>m.ret(f(x)))
}
案例类Comp[M[uuz],N[uz],a](未编译:M[N[a]]
类CompApp[M[u],N[]](隐式mapp:Applicative[M],napp:Applicative[N])扩展了Applicative[({typeλ[α]=Comp[M,N,α]})#λ]{
def pure[a](x:a)=Comp(mapp.pure(napp.pure(x)))
def comp[a,b](mf:comp[M,N,a=>b])(mx:comp[M,N,a])=comp(mapp.comp(mapp.comp(mapp.pure(napp.comp[a,b]))(mf.unco))(mx.unco))
}
对象主{
隐式定义索引顺序:可遍历[树]=新可遍历[树]{
def dist[a,M[+]](t:Tree[M[a]](隐式应用程序:Applicative[M])
=不匹配{
case Empty()=>app.pure(Empty())
案例节点(x,l,r)=>app.comp(app.comp(app.pure)(l:Tree[a])=>((x:a)=>((r:Tree[a])=>Node(x,l,r∗∗∗);(dist(l)(app))(x))(dist(r)(app))
}
}   
val emptyTree=空[Int]()
val tree2=Node(5,Node(2,Empty(),Empty()),Node(9,Empty(),Empty())
隐式def stateMonad[a]=新stateMonad[a]()
隐式def monadApp=新的monadApp[({typeλ[α]=状态[Int,α]})#λ](){}
隐式def和monoidapp=新的MonoidApplicative[Boolean]()(BoolAnd);
隐式def stateMonidComp=new CompApp[({typeκ[β]=State[Int,β]})#κ,({typeλ[α]=K[布尔,α]})#λ]()(monadApp和monoidapp)
def pairSort(x:Int):状态[Int,布尔]
=状态((y:Int)=>(y)
Comp[({typeκ[β]=状态[Int,β]})#κ,({typeλ[α]=K[布尔,α]})#λ,布尔]
(as.fmap[Boolean,K[Boolean,Boolean]]((x:Boolean)=>K[Boolean,Boolean](x))(pairSort(i)))
)
(t)
//(CompApp[({typeκ[β]=状态[Int,β]})#κ,({typeλ[α]=K[布尔,α]})#λ])
(StateMonidComp)
).unComp.func(-10000)
)1.价值
def main(参数:数组[字符串])
=println(“已排序”+已排序(tree2)(monadApp,inOrder));
}

问题在于您有两种不同的类型:
可遍历的[节点]
可遍历的[树]
。这来自Haskell的ADT翻译。而在Haskell
节点中
都是
,而在Scala中它们是
的子类型,这导致了方差的概念发挥作用:给定
A
B
的子类型,是
T[A]
A
T[B]
的子类型吗

如果我们看一个函数的类型
X=>Y
,我们会看到它被声明为
Function1[-X,+Y]
,也就是说,它在
X
中是逆变的,在
Y
中是协变的。这意味着接受
并返回
节点
的函数是接受
节点
并返回
的函数的子类型。例如:

def f[T](n: Node[T])(func: Node[T] => Tree[T]): Tree = func(n)
def zeroRoot(tree: Tree[Int]): Node[Int] = Node(0, tree, Empty())
f(Node(1, Empty(), Empty())(zeroRoot)
函数
zeroot
起作用,因为我们正在向它传递一个
节点
,它需要一个
(这是正常的),然后我们返回了一个
节点
,该节点反过来作为
(也正常)返回