Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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:二进制操作的类型界限_Scala_Monoids_Type Bounds - Fatal编程技术网

scala:二进制操作的类型界限

scala:二进制操作的类型界限,scala,monoids,type-bounds,Scala,Monoids,Type Bounds,问题很简单,我有一个对象,它使用两个参数执行二进制操作。我只想添加相同类型的燃油,如下所示: object Fuels { case class Fuel[F <: FuelType](amount: Double, fuelType: F = Petrol) { def +(that : Fuel[F]) = { copy(amount = this.amount + that.amount) } } def add[F <: FuelT

问题很简单,我有一个对象,它使用两个参数执行二进制操作。我只想添加相同类型的燃油,如下所示:

object Fuels {

  case class Fuel[F <: FuelType](amount: Double, fuelType: F = Petrol) {
    def +(that : Fuel[F]) = {
      copy(amount = this.amount + that.amount)
    }
  }

  def add[F <: FuelType](x: Fuel[F], y: Fuel[F]): Fuel[F] = x + y

  sealed trait FuelType {
    val name : String
  }
  case object Petrol extends FuelType{
    override val name = "Petrol"
  }
  case object Diesel extends FuelType{
    override val name = "Diesel"
  }
  case object Hydrogen extends FuelType{
    override val name = "Hydrogen"
  }

 implicit def fuelMonoid[F <:FuelType](implicit fuelType: F) = new Monoid[Fuel]{
     override def zero: Fuel[F] = Fuel(0, fuelType)
     override def append(m1: Fuel[F], m2: Fuel[F]) : Fuel[F] = m1 + m2
   }

}
编译错误:

Expression of Type Fuels.Fuel[Nothing] does not conform to Fuels.Fuel[F]
主要问题是add和fuelMonoid都无法确定我们处理的是相同类型的项。编译器无法解析类型约束,无法推断任何内容

为了完成,这里是幺半群,没有什么特别的:

trait Monoid[A] {
  def zero: A
  def append(a1: A, a2: A): A
}

我将类型更改为
Monoid[Fuel[F]]
,指定返回类型为
implicit def
Fuel++
,它可以工作:

object Fuels {

  trait Monoid[F] {
    def zero: F
    def append(f1: F, f2: F): F
  }

  object Monoid {
    def fold[F](as: Seq[F], m: Monoid[F]): F = as.foldLeft(m.zero)(m.append)
  }

  case class Fuel[F <: FuelType](amount: Double, fuelType: F = Petrol) {
    def +(that : Fuel[F]): Fuel[F] = {
      copy(amount = this.amount + that.amount)
    }
  }

  def add[F <: FuelType](x: Fuel[F], y: Fuel[F]): Fuel[F] = x + y

  sealed trait FuelType {
    val name : String
  }
  case object Petrol extends FuelType{
    override val name = "Petrol"
  }
  case object Diesel extends FuelType{
    override val name = "Diesel"
  }
  case object Hydrogen extends FuelType{
    override val name = "Hydrogen"
  }

  implicit def fuelMonoid[F <:FuelType](implicit fuelType: F): Monoid[Fuel[F]] = new Monoid[Fuel[F]] {
    override def zero: Fuel[F] = Fuel(0, fuelType)
    override def append(m1: Fuel[F], m2: Fuel[F]): Fuel[F] = m1 + m2
  }
}

object Main {
  def main (args: Array[String] ) {
    import Fuels._
    println(Fuel(10, Petrol) + Fuel(20, Petrol))
    println(add(Fuel(10, Petrol), Fuel(20, Petrol)))
    println(Monoid.fold(Seq(Fuel(10, Petrol), Fuel(20, Petrol), Fuel(30, Petrol)), fuelMonoid(Petrol)))
  }
}
对象燃料{
特征幺半群[F]{
def零:F
def附加(f1:F,f2:F):F
}
对象幺半群{
def fold[F](as:Seq[F],m:Monoid[F]):F=as.foldLeft(m.zero)(m.append)
}

case class Fuel[F
Monoid
的定义是什么?如果我将其定义为
trait Monoid[M]{def zero:M;def append(m1:M,m2:M):M}
,那么如果不将
fuelMonoid
的类型更改为
隐式def fuelMonoid,我就无法编译代码[F幺半群特征确实是这样定义的,我将在主要问题中添加代码。添加新的幺半群[Fuel[F]]而不是新的幺半群[Fuel]没有什么区别,原因与添加(x,y)相同不起作用。有什么建议吗?发生了一些非常奇怪的事情。Intellij Idea报告了各种错误。使用Scalaz,我能够利用第二个参数,即按名称调用,其中我的版本需要一个严格的参数。我将继续对其进行修补,以使其正常工作,但很高兴知道解决方案应该有效问题是Intellij IDEA。识别类型的荧光笔肯定有一些错误。顺便问一下,你知道如何使用你建议的附加来进行折叠操作吗:trait Monoid[a]{def append(a1:a,a2:=>a):def zero:a}object Monoid{def fold[a](as:Seq[a],m:Monoid[a]):a=as.foldLeft(m.zero)(m.append)}。我不想为了这个而使用完整的Scalaz。谢谢!@fracca,对不起,我没有注意到你使用了自己的
Monoid
。我和你一样,在非Scalaz特性上也会遇到同样的奇怪错误。我会尝试再修改一下。@fracca,看起来我已经找到了你两个问题的答案。我编辑了答案(添加了简单的
Monoid
trait和
Monoid
对象和
fold
)。
object Fuels {

  trait Monoid[F] {
    def zero: F
    def append(f1: F, f2: F): F
  }

  object Monoid {
    def fold[F](as: Seq[F], m: Monoid[F]): F = as.foldLeft(m.zero)(m.append)
  }

  case class Fuel[F <: FuelType](amount: Double, fuelType: F = Petrol) {
    def +(that : Fuel[F]): Fuel[F] = {
      copy(amount = this.amount + that.amount)
    }
  }

  def add[F <: FuelType](x: Fuel[F], y: Fuel[F]): Fuel[F] = x + y

  sealed trait FuelType {
    val name : String
  }
  case object Petrol extends FuelType{
    override val name = "Petrol"
  }
  case object Diesel extends FuelType{
    override val name = "Diesel"
  }
  case object Hydrogen extends FuelType{
    override val name = "Hydrogen"
  }

  implicit def fuelMonoid[F <:FuelType](implicit fuelType: F): Monoid[Fuel[F]] = new Monoid[Fuel[F]] {
    override def zero: Fuel[F] = Fuel(0, fuelType)
    override def append(m1: Fuel[F], m2: Fuel[F]): Fuel[F] = m1 + m2
  }
}

object Main {
  def main (args: Array[String] ) {
    import Fuels._
    println(Fuel(10, Petrol) + Fuel(20, Petrol))
    println(add(Fuel(10, Petrol), Fuel(20, Petrol)))
    println(Monoid.fold(Seq(Fuel(10, Petrol), Fuel(20, Petrol), Fuel(30, Petrol)), fuelMonoid(Petrol)))
  }
}