标签: shapeless

通常重写Scala案例类

是否可以一般性地替换案例类中的参数?更具体地说,我想要一个替代函数,它接收一个"查找"案例类和一个"替换"案例类(如语法规则的左侧和右侧)以及一个目标案例类,该函数将返回一个将case case类的参数替换为replace case类的新case类?该函数还可以简单地将case类(Product?)和一个函数应用于case类的所有参数/产品.

显然,给定一个特定的case类,我可以使用unapply和apply - 但是一般来说(给定任何case类)编写这种函数的最好/最简单/等方法是什么?

我想知道是否有一个很好的解决方案,使用Scala 2.10反射功能或无形的Iso.hlist.

例如,我真正希望能够做的是,给出如下的类......

class Op[T]
case class From(x:Op[Int]) extends Op[Int]
case class To(x:Op[Int]) extends Op[Int]

case class Target(a:Op[Int], b:Op[Int]) extends ...
// and lots of other similar case classes
Run Code Online (Sandbox Code Playgroud)

...有一个函数可以接受任意的case类并返回它的副本,其中任何类型的元素都替换为To类型的实例.

reflection scala case-class shapeless

4
推荐指数
1
解决办法
1032
查看次数

如何在HLists上实现zipWithIndex

编写算法HList,我需要一个zipWithIndex函数.它现在不在无形图书馆,所以我决定实施它.

很明显它可能被实现为

hlist.zip(indexes)
Run Code Online (Sandbox Code Playgroud)

这里indexesHList索引(0到n),这可能可以得到这样的:

val indexes = Nat._0 until hlist.length
Run Code Online (Sandbox Code Playgroud)

这里的问题是Nat没有until方法.我还没有发现任何WitnessHList与使用索引HList.map.

什么是我可以用它来获取方法HListNat以S开始Nat._0hlist.length

scala hlist shapeless

4
推荐指数
1
解决办法
353
查看次数

Scala:基于类型的列表分区

我有这个代码,我想改进:

sealed abstract class A
case class B() extends A
case class C() extends A
case class D() extends A

case class Foo[+T <: A](a: T)

/** Puts instances that match Foo(B()) in the first list and everything else,
  * i.e. Foo(C()) and Foo(D()), in the second list. */
def partition(foos: List[Foo[_ <: A]]): (List[Foo[B]], List[Foo[_ <: A]]) = {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我想在以下方面对此进行改进:

  1. 我可以更改其partition返回类型,以便它表明Foo[B]第二个列表中没有吗?
  2. 我可以摆脱Foo类型参数T(即更改Foocase class Foo(a: A) …

types scala shapeless

4
推荐指数
1
解决办法
402
查看次数

什么是避免无形的两个类型定义之间发生冲突的最佳方法

Shapeless有一个简洁的类型派生机制,允许您定义类型类并获得任何类型类的自动派生.

要将派生机制用作类型类的用户,可以使用以下语法

import MyTypeClass.auto._
Run Code Online (Sandbox Code Playgroud)

据我所知,它相当于

import MyTypeClass.auto.derive
Run Code Online (Sandbox Code Playgroud)

当您尝试在同一范围内尝试使用多个类型类时会出现问题.看起来Scala编译器只考虑了derive的最后一个定义,即使它的隐式参数有两个版本的函数"重载".

我可以通过几种方法来解决这个问题.我不会在这里列出它们,而是将它们标记为答案,您可以投票确认理智并提出任何更好的解决方案.

scala typeclass type-level-computation shapeless scala-macros

4
推荐指数
1
解决办法
155
查看次数

基于Scala类型的属性提取器 - 仅限Getter镜头?

从数据容器(例如案例类)中提取类型的最佳方法是什么.

例如,如果我有type Tagged[U] = { type Tag = U}标记类型trait PID,标记为Int type ProductId = Int with Tagged[PID]或scalaz样式,type ProductId = Int @@ PID并说明产品type Name = String @@ PName等中的其他字段和包含产品属性的数据容器;

case class Product(pid: ProductId, name: Name, weight: Weight)
Run Code Online (Sandbox Code Playgroud)

如何在A => B不诉诸反射的情况下编写通用的提取器样式方法?

原因是我想在运行时从Product容器中动态提取字段.即,用户传递他们想要提取的产品的属性.

即如果我想动态获取ProductId,我可以编写一个接受类型并返回值的方法,例如

trait Extractor[A] {
  def extract[B](i: A): B = //get type B from the Product class
}
Run Code Online (Sandbox Code Playgroud)

或者我是在复杂的事情.

我可以编写简单的提取器类,它采用A => B函数并为每种类型定义它;

trait Getter[A, B] {
  def extract(i: A): B …
Run Code Online (Sandbox Code Playgroud)

generics scala scalaz lenses shapeless

4
推荐指数
1
解决办法
551
查看次数

如何用HList调用多个参数的函数?

假设我有一个HList类型A::B::C::HNil和一个函数(A, B, C) => D

val hlist: A::B::C::HNil = ???
def foo(a: A, b: B, c: C): D = ???
Run Code Online (Sandbox Code Playgroud)

现在我需要一个功能可按A::B::C::HNil => D,它使用foo返回D.

def bar(hslist: A::B::C::HNil): D = ???
Run Code Online (Sandbox Code Playgroud)

你会如何实施bar

scala shapeless

4
推荐指数
1
解决办法
357
查看次数

foldRight后的无形HList地图

类型级别foldRight工作正常(getLabelWithValues),后续类型级别map(getValues)也可以正常工作.如果我在一个方法(getValuesFull)中组合两者,它就不再起作用了.丢失的是什么?

完整的源代码(sbt准备好~run使用隐式调试输出)在这里:https://github.com/mpollmeier/shapeless-playground/tree/8170a5b

case class Label[A](name: String)
case class LabelWithValue[A](label: Label[A], value: A)

val label1 = Label[Int]("a")
val labels = label1 :: HNil

object combineLabelWithValue extends Poly2 {
  implicit def atLabel[A, B <: HList] = at[Label[A], (B, Map[String, Any])] {
    case (label, (acc, values)) ?
      (LabelWithValue(label, values(label.name).asInstanceOf[A]) :: acc, values)
  }
}

object GetLabelValue extends (LabelWithValue ~> Id) {
  def apply[B](labelWithValue: LabelWithValue[B]) = labelWithValue.value
}

val labelsWithValues: LabelWithValue[Int] :: HNil = getLabelWithValues(labels) …
Run Code Online (Sandbox Code Playgroud)

scala implicit shapeless

4
推荐指数
1
解决办法
220
查看次数

为什么scalac在这里出现"分歧的隐式扩展"错误?

在下面的代码中,我尝试使用shapeless派生类型类实例.但是,在更复杂的案例类(转换为更复杂的HList)的情况下,编译器给我一个"分歧的隐式扩展",即使它似乎没有两次解析相同类型的隐式类型.也许我错过了编译器的其他一些规则?

(小提琴:https://scalafiddle.io/sf/WEpnAXN/0)

import shapeless._

trait TC[T]

sealed trait Trait1
case class SimpleClass(a: String) extends Trait1

sealed trait Trait2
case class ComplexClass(a: String, b: String) extends Trait2

object Serialization extends App {

    //Instances for HList
    implicit val hnilInstance: TC[HNil] = ???
    implicit def hconsInstance[H, T <: HList] (implicit t: TC[T]): TC[H :: T] = ???

    //Instances for CoProduct
    implicit val cnilInstance: TC[CNil] = ???
    implicit def cconsInstance[H, T <: Coproduct] (implicit h: TC[H], t: TC[T]): TC[H :+: …
Run Code Online (Sandbox Code Playgroud)

scala implicit typeclass shapeless

4
推荐指数
1
解决办法
456
查看次数

简单的无形HLIST上的模式匹配

我使用无形库编写了这个简单的代码

import shapeless.LabelledGeneric
case class Icecream(name: String, numberOfCherries: Int, inCone: Boolean)

object ShapelessRecordEx2 extends App {
   val gen = LabelledGeneric[Icecream]
   val hlist = gen.to(Icecream("vanilla", 2, false))
   hlist match {
      case h :: _ => println(h)
   }
}
Run Code Online (Sandbox Code Playgroud)

但是甚至没有编译

Error:(12, 14) constructor cannot be instantiated to expected type;
 found   : scala.collection.immutable.::[B]
 required: shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("numberOfCherries")],Int],shapeless.::[Boolean with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("inCone")],Boolean],shapeless.HNil]]]
      case h :: _ => println(h)
Run Code Online (Sandbox Code Playgroud)

如果我正在使用普通列表,那么这段代码就可以了.

scala shapeless

4
推荐指数
1
解决办法
690
查看次数

使用无形状HList时减少编译时间

Scala 2.12.6,无形2.3.3

我有很多很深的大型模型(案例类)。我使用shapeless来帮助使用/操纵这些模型,还使用诸如circe之类的库,这些库大量使用了shapeless。

这导致我的编译时间在phase typerscalac 期间大大增加。

基于一点谷歌搜索,看起来无形是罪魁祸首,但是我似乎找不到任何有关如何改进它的具体技巧。

有人建议,因为我要为同一模型多次解析HList隐式(由于有多个库),所以我应该“缓存”它们-但是我不确定如何确切地找出要缓存的内容。

给出类似的东西:

case class MyModel(value: String) extends AnyVal
case class MyOtherModel(value: Int) extends AnyVal
case class MyRootModel(myModel: MyModel, myOtherModel: MyOtherModel)
Run Code Online (Sandbox Code Playgroud)

我应该为MyModel/ MyOtherModel和缓存什么MyRootModel

scala shapeless

4
推荐指数
1
解决办法
234
查看次数