Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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 如何减少受约束的HList_Scala_Shapeless - Fatal编程技术网

Scala 如何减少受约束的HList

Scala 如何减少受约束的HList,scala,shapeless,Scala,Shapeless,如何修复下面的代码使其工作 object Foo { object sum extends Poly { implicit def caseFoo = use((f1: Int, f2: Int) => f1 + f2) } def foo[L <: HList : <<:[Int]#λ](l: L): Int = { l.reduceLeft(sum) // Error: could not find implicit value

如何修复下面的代码使其工作

object Foo {
  object sum extends Poly {
    implicit def caseFoo = use((f1: Int, f2: Int) => f1 + f2)
  }

  def foo[L <: HList : <<:[Int]#λ](l: L): Int = {
    l.reduceLeft(sum)
    // Error: could not find implicit value for parameter reducer: shapeless.ops.hlist.LeftReducer[L,com.struct.Foo.sum.type] 
    //   l.reduceLeft(sum)
    // Error: not enough arguments for method reduceLeft: (implicit reducer: shapeless.ops.hlist.LeftReducer[L,com.struct.Foo.sum.type])reducer.Out. 
    //   Unspecified value parameter reducer.
  }
}
objectfoo{
对象和扩展多边形{
隐式def caseFoo=use((f1:Int,f2:Int)=>f1+f2)
}

def foo[L约束。此功能:

package com.test

import shapeless.ops.hlist.LeftReducer
import shapeless.{HList, HNil, Poly}

trait Bar {
  def foo: Int
}

case class Foo[L <: HList](list: L) extends Bar {
  import Numeric.Implicits._
  object sum extends Poly {
    implicit def caseFoo[A: Numeric] = use((f1: A, f2: A) => f1 + f2)
  }

  class MkFoo[T] {
    def apply(l: L)(implicit reducer: LeftReducer.Aux[L, sum.type, T]): T = reducer(l)
  }

  override def foo: Int = (new MkFoo[Int]())(list)
  // Error: could not find implicit value for parameter reducer: shapeless.ops.hlist.LeftReducer.Aux[L,Foo.this.sum.type,Int]

}

object Testing {
  def main(args: Array[String]): Unit = {
    val b:Bar  = Foo(1 :: 2 :: 3 :: HNil)
    println(b.foo)
  }

}
package com.test

import shapeless.{::, Generic, HList, HNil, Lazy}


trait Bar {
  def foo: Int
}

case class Foo[L <: HList](list: L)(implicit ev: SizeCalculator[L]) extends Bar {
  override def foo: Int = ev.size(list)
}

object Testing {
  def main(args: Array[String]): Unit = {
    val b: Bar = Foo(1 :: 2 :: 3 :: HNil)
    println(b.foo)
  }
}


sealed trait SizeCalculator[T] {
  def size(value: T): Int
}

object SizeCalculator {

  // "Summoner" method
  def apply[A](implicit enc: SizeCalculator[A]): SizeCalculator[A] = enc

  // "Constructor" method
  def instance[A](func: A => Int): SizeCalculator[A] = new SizeCalculator[A] {
    def size(value: A): Int = func(value)
  }

  import Numeric.Implicits._

  implicit def numericEncoder[A: Numeric]: SizeCalculator[A] = new SizeCalculator[A] {
    override def size(value: A): Int = value.toInt()
  }

  implicit def hnilEncoder: SizeCalculator[HNil] = instance(hnil => 0)

  implicit def hlistEncoder[H, T <: HList](
                                            implicit
                                            hInstance: Lazy[SizeCalculator[H]],
                                            tInstance: SizeCalculator[T]
                                          ): SizeCalculator[H :: T] = instance {
    case h :: t =>
      hInstance.value.size(h) + tInstance.size(t)
  }

  implicit def genericInstance[A, R](
                                      implicit
                                      generic: Generic.Aux[A, R],
                                      rInstance: Lazy[SizeCalculator[R]]
                                    ): SizeCalculator[A] = instance { value => rInstance.value.size(generic.to(value)) }


  def computeSize[A](value: A)(implicit enc: SizeCalculator[A]): Int = enc.size(value)
}
package.com.test
导入无形状。{::,泛型,HList,HNil,Lazy}
特征条{
def foo:Int
}
案例类Foo[L Int):SizeCalculator[A]=新的SizeCalculator[A]{
def大小(值:A):Int=func(值)
}
导入Numeric.Implicits_
隐式def numericEncoder[A:数值]:SizeCalculator[A]=新的SizeCalculator[A]{
覆盖def大小(值:A):Int=value.toInt()
}
隐式定义hnilEncoder:SizeCalculator[HNil]=实例(HNil=>0)
隐式def hlistEncoder[H,T
hInstance.value.size(h)+tInstance.size(t)
}
隐式定义泛型常量[A,R](
含蓄的
generic:generic.Aux[A,R],
冲洗液:惰性[SizeCalculator[R]]
):SizeCalculator[A]=实例{value=>rInstance.value.size(generic.to(value))}
def computeSize[A](值:A)(隐式enc:SizeCalculator[A]):Int=enc.size(值)
}

Hi@Odomontis,谢谢你的回答。但我有以下问题。1.f1+f2不起作用,因为数字没有定义+。用“加号”替换它没有帮助,因为我想可能需要对数字进行参数化。2.在你的解决方案中,你更改了foo签名。现在不是返回Int,而是声明返回reducer.Out。如果Foo需要实现一个定义“def foo():Int”的trait,foo接受[L@Lambder,是否包含
数值隐式导入?@Lambder
数值
不需要类型参数,因为它在positionBar中使用。size不接受参数…foo应该是case类扩展条
import shapeless._, ops.hlist._

object Foo {
  import Numeric.Implicits._
  object sum extends Poly {
    implicit def caseFoo[A: Numeric] = use((f1: A, f2: A) => f1 + f2)
  }

  def foo[L <: HList](l: L)(implicit reducer: LeftReducer[L, sum.type]): reducer.Out = 
    reducer(l)
}


Foo.foo(1 :: 2 :: 3 :: HNil) // res0: Int = 6

Foo.foo(1.0 :: 2.0 :: 3.0 :: HNil) // res1: Double = 6.0
object Foo {
  import Numeric.Implicits._
  object sum extends Poly {
    implicit def caseFoo[A: Numeric] = use((f1: A, f2: A) => f1 + f2)
  }

  def foo[T] = new MkFoo[T]

  class MkFoo[T] {
    def apply[L <: HList](l: L)(implicit reducer: LeftReducer.Aux[L, sum.type, T]): T = reducer(l)
  }
}
Foo.foo[Int](1 :: 2 :: 3 :: HNil)
Foo.foo[Double](1.0 :: 2.0 :: 3.0 :: HNil)
Foo.foo[Double](1 :: 2 :: 3 :: HNil)
package com.test

import shapeless.{::, Generic, HList, HNil, Lazy}


trait Bar {
  def foo: Int
}

case class Foo[L <: HList](list: L)(implicit ev: SizeCalculator[L]) extends Bar {
  override def foo: Int = ev.size(list)
}

object Testing {
  def main(args: Array[String]): Unit = {
    val b: Bar = Foo(1 :: 2 :: 3 :: HNil)
    println(b.foo)
  }
}


sealed trait SizeCalculator[T] {
  def size(value: T): Int
}

object SizeCalculator {

  // "Summoner" method
  def apply[A](implicit enc: SizeCalculator[A]): SizeCalculator[A] = enc

  // "Constructor" method
  def instance[A](func: A => Int): SizeCalculator[A] = new SizeCalculator[A] {
    def size(value: A): Int = func(value)
  }

  import Numeric.Implicits._

  implicit def numericEncoder[A: Numeric]: SizeCalculator[A] = new SizeCalculator[A] {
    override def size(value: A): Int = value.toInt()
  }

  implicit def hnilEncoder: SizeCalculator[HNil] = instance(hnil => 0)

  implicit def hlistEncoder[H, T <: HList](
                                            implicit
                                            hInstance: Lazy[SizeCalculator[H]],
                                            tInstance: SizeCalculator[T]
                                          ): SizeCalculator[H :: T] = instance {
    case h :: t =>
      hInstance.value.size(h) + tInstance.size(t)
  }

  implicit def genericInstance[A, R](
                                      implicit
                                      generic: Generic.Aux[A, R],
                                      rInstance: Lazy[SizeCalculator[R]]
                                    ): SizeCalculator[A] = instance { value => rInstance.value.size(generic.to(value)) }


  def computeSize[A](value: A)(implicit enc: SizeCalculator[A]): Int = enc.size(value)
}