Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用scala在容器类型上编写typeclass,从容器返回元素?_Scala_Typeclass - Fatal编程技术网

如何用scala在容器类型上编写typeclass,从容器返回元素?

如何用scala在容器类型上编写typeclass,从容器返回元素?,scala,typeclass,Scala,Typeclass,在下面的程序中,我试图让typeclass工作。typeclass是Algo,它的实际实现需要一个容器[\up>编译: trait Algo[T, C <: Container[T]] { def algo(t : C) : Option[T] } object Algo { implicit def impl[T <: Id, C <: Container[T]] = new Algo[T,C] { def algo(cont : C) :

在下面的程序中,我试图让typeclass工作。typeclass是Algo,它的实际实现需要一个容器[\up>编译:

trait Algo[T, C <: Container[T]] {
    def algo(t : C) : Option[T]
}

object Algo {
    implicit def impl[T <: Id, C <: Container[T]] = new Algo[T,C] {
        def algo(cont : C) : Option[T] = {
            Some(cont.value)
        }
    }

    implicitly[Algo[ElementWithId,Container[ElementWithId]]].algo(new Container[ElementWithId] {
                                                  override val value = new ElementWithId
                                              })
}
trait Algo[T,C编译:

trait Algo[T, C <: Container[T]] {
    def algo(t : C) : Option[T]
}

object Algo {
    implicit def impl[T <: Id, C <: Container[T]] = new Algo[T,C] {
        def algo(cont : C) : Option[T] = {
            Some(cont.value)
        }
    }

    implicitly[Algo[ElementWithId,Container[ElementWithId]]].algo(new Container[ElementWithId] {
                                                  override val value = new ElementWithId
                                              })
}

trait Algo[T,C您的第一个问题是,在您的Algo实现中,您返回
value
,它被声明为
T
类型,但期望它是
T#Elem
(您的意思可能是
cont.Elem
,更准确)。类型恰好相同,但编译器不会检查。如果您声明
val value:ElemType
,则可以开始执行某个操作

如果同时使用类型参数T和类型成员ElemType,则会带来很多复杂性,您也应该选择其中一个

trait Container[T <: Element] {
  val value : T // might be wiser to avoid abstract val and prefer abstract def
}
我宁愿选择第一个。 因此,正确编写Algo将是

trait Algo[C[X <: Element] <: Container[X]] {
  def algo[A <: Element](c: C): Option[A]
}

trait Algo[C[X您的第一个问题是,在您的Algo实现中,您返回
,该值被声明为
T
类型,但期望它是
T#Elem
(您的意思可能是
cont.Elem
,更准确)。类型恰好相同,但编译器不会检查。如果您声明
val value:ElemType
,则可以开始执行某个操作

如果同时使用类型参数T和类型成员ElemType,则会带来很多复杂性,您也应该选择其中一个

trait Container[T <: Element] {
  val value : T // might be wiser to avoid abstract val and prefer abstract def
}
我宁愿选择第一个。 因此,正确编写Algo将是

trait Algo[C[X <: Element] <: Container[X]] {
  def algo[A <: Element](c: C): Option[A]
}

trait算法[C][X谢谢你的回答!但是我忘了添加要求,你能告诉我问题中的更新部分是否也可以吗?谢谢你的回答!但是我忘了添加要求,你能告诉我问题中的更新部分是否也可以吗?谢谢你的回答!但是我忘了添加要求,你能告诉我r问题中的更新部分也是可能的?@MHOOO是的,只是删除你不想要的边界。(参见更新的答案)奇怪,它对我不起作用。我得到(在注释中不起作用…:[错误]测试。scala:118:类型参数[T]不符合trait容器的类型参数边界[T@mhoo可能是这样,但是如果您想要一个
容器[T哦,这是对的。那么有没有办法让容器本身成为一种类型,这样我就可以完全从Algo特性中摆脱对它的依赖?谢谢你的回答!但是我忘了添加一个要求,你能告诉我问题中的更新部分是否也可能吗?@mhoo是的,只要去掉你没有的边界就行了want.(参见更新的答案)奇怪,它对我不起作用。我得到(不在注释中工作…:[error]测试。scala:118:类型参数[T]不符合trait容器的类型参数边界[T@MHOOO可能是,但如果您想要
容器哦,这是对的。那么,有没有办法让容器本身成为一个类型,这样我就可以完全从Algo特性中摆脱对它的依赖?
trait Algo[A <: Element, C <: C[A]] {
  def algo(c: C[A]): Option[A]
}
trait Algo[R <: ElementType, C[X <: R] <: Container[X]] {
   def algo[A <: R](c: C[A]): Option[A]
}
trait Algo4[R, C[X <: Element with R] <: Container[X]] {
  def algo[A <: Element with R] (c: C[A]) : Option[A]
}