标签: shapeless

使用 Shapeless + LabelledGenerics 一般地将一个类变形为另一个类

我知道使用 Shapeless 我可以做这样的事情:

  import shapeless._, syntax.singleton._, record._

  case class Foo(x: Int, y: String)
  case class RichFoo(x: Int, y: String, z: Double)

  def makeRich(foo: Foo): RichFoo = {
    val x = ('z ->> 0.9)
    val repr = LabelledGeneric[Foo].to(foo) + x
    LabelledGeneric[RichFoo].from(repr)
  }

  val a = Foo(1, "hello")
  val b = makeRich(a)
Run Code Online (Sandbox Code Playgroud)

现在我想写一个通用的方法来做到这一点:

trait Morph[A, B, AR, BR] {
  def apply(a: A)(f: AR => BR): B
}

object Morph {
  implicit def genericMorph[A, B, AR, BR](implicit genA: LabelledGeneric.Aux[A, AR], genB: LabelledGeneric.Aux[B, BR]): …
Run Code Online (Sandbox Code Playgroud)

scala type-level-computation shapeless labelled-generic

3
推荐指数
1
解决办法
128
查看次数

什么时候需要 Shapeless 中的依赖类型?

据我了解,依赖类型允许您不指定输出类型:

例如,如果您有一个类型类:

trait Last[In] {
  type Out
}
Run Code Online (Sandbox Code Playgroud)

那么你可以在不指定输出类型的情况下召唤一个实例:

implicitly(Last[String :: Int :: HNil]) // output type calculated as Int
Run Code Online (Sandbox Code Playgroud)

Aux 模式允许您再次指定输出类型:

implicitly(Last.Aux[String :: Int :: HNil, Int])
Run Code Online (Sandbox Code Playgroud)

您需要在隐式参数列表中使用它,以便对输出类型做一些有用的事情(解决 Scala 对依赖类型的限制)。

但是如果你总是需要指定(或分配一个类型参数)输出类型,为什么首先要使用依赖类型(然后是 Aux)呢?

我尝试Last从 Shapeless 的 src复制类型类,替换type Out为特征中的附加类型参数并删除 Aux。它仍然有效。

当我真正需要它们时是什么情况?

scala dependent-type shapeless

3
推荐指数
1
解决办法
375
查看次数

将 Ei 的 HList 转换为 HList 的任一个

我想定义一个函数,它接受一个 ,HList其元素是这样的,对于每个元素t,都有一个类型T使得t: Either[String, T]. 我们将调用的函数validate应具有以下行为:

  • 如果参数的所有元素都是Right,则返回Right右投影映射参数的结果。
  • 否则,返回 a Left[List[String]],其中列表包含Left参数中每个的左投影。

例子:

validate (Right (42) :: Right (3.14) :: Right (false) :: HNil)
>> Right (42 :: 3.14 :: false :: HNil)
Run Code Online (Sandbox Code Playgroud)
validate (Right (42) :: Left ("qwerty") :: Left ("uiop") :: HNil)
>> Left (List ("qwerty", "uiop"))
Run Code Online (Sandbox Code Playgroud)

一个示例用例:

case class Result (foo: Foo, bar: Bar, baz: Baz, qux: Qux)

def getFoo: Either[String, Foo] = …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

3
推荐指数
1
解决办法
228
查看次数

如何使用shapeless在scala中实现[x] - > x?

def unreturn(lx: Sized[List[Int], Nat._1]): Int = lx head
Run Code Online (Sandbox Code Playgroud)

如何使用shapeless获取一个元素列表的头部?这不编译:

No implicit view available from List[Int] =>
scala.collection.GenTraversableLike[v.A,List[Int]].

not enough arguments for method sizedOps:
(implicit evidence$2: List[Int] =>
scala.collection.GenTraversableLike[v.A,List[Int]])shapeless.
SizedOps[v.A,List[Int],shapeless.Nat._1]. Unspecified value parameter evidence$2.
Run Code Online (Sandbox Code Playgroud)

scala shapeless

2
推荐指数
1
解决办法
253
查看次数

使用HLists作为函数的参数

是否可以将HList作为函数参数传递?

这是我到目前为止:

import shapeless._
import poly._

object id extends (Id ~> Id) {
  def apply[T](f: shapeless.Id[T]): shapeless.Id[T] = f
}

object ListHandler {
  def mapOverHlist[ListType <: HList](list: ListType) = list.map(id)
}

val x = "foo" :: "bar" :: 0xb33f :: HNil    
ListHandler.mapOverHlist(x)
Run Code Online (Sandbox Code Playgroud)

导致此错误:

could not find implicit value for parameter mapper:   
shapeless.ops.hlist.Mapper[ShapelessSpec.this.id.type,ListType]
Run Code Online (Sandbox Code Playgroud)

scala shapeless

2
推荐指数
1
解决办法
763
查看次数

案例类修改和设计通用方法

为了这篇文章的目的,代码片段被轻视,抽样.

case class Person(firstName:String,lstName:String)
Run Code Online (Sandbox Code Playgroud)

此人类已在代码库中的所有位置使用.现在,后来的需求发生了变化,并决定phoneNumber在人案例类中添加

例如

case class Person(firstName:String,lstName:String,phoneNumber:String)
Run Code Online (Sandbox Code Playgroud)

再次,帖子中的例子极为简化.实际上,有更多有趣的事情正在发生.请注意,这phoneNumber不是Option必填字段.通常,人们会更新所有使用Person类的代码,以满足新领域的需求lastName.当你有100个引用它时,这是相当繁琐的.

HList从get get vs case class 创建更灵活的无形帮助?

scala shapeless

2
推荐指数
1
解决办法
89
查看次数

如何在Scala中实现异构容器

我需要一个异构的,类型安全的容器来存储不相关的类型A,B,C.

这是一种类型级规范:

trait Container {
  putA(a: A) 
  putB(b: B)
  putC(c: C)
  put(o: Any) = { o match {
    case a: A => putA(a)
    case b: B => putB(b)
    case c: C => putC(c)
  }
  getAllAs : Seq[A]
  getAllBs : Seq[B]
  getAllCs : Seq[C]
}
Run Code Online (Sandbox Code Playgroud)

哪种类型是支持此容器的最佳套件?

是否值得为类型A,B,C创建容器[T]类型类?

THKS.

collections scala heterogeneous shapeless

2
推荐指数
1
解决办法
1024
查看次数

了解Parboiled2的'〜'组合器

看看parboiled2部分,Rule Combinators and Modifiers:

在此输入图像描述

我不明白的a,b和再a ~ b图.

到目前为止,我发现文档很简单.但在这里有点失落.

你能解释一下这个街区吗?

shapeless parboiled2

2
推荐指数
1
解决办法
118
查看次数

使用无形来合并同一案例类的两个实例

我想将类的更新实例合并到基本实例中,如果基本实例中的该字段为"空",则选择基础实例上的更新实例的字段.以下示例合并baseupdate:

case class Foo(a: Option[Int], b: List[Int], c: Option[Int])

val base = Foo(None, Nil, Some(0))
val update = Foo(Some(3), List(4), None)

merge(base,update) == Foo(Some(3), List(4), Some(0))
Run Code Online (Sandbox Code Playgroud)

我尝试过这样的事情:

val g = Generic[Foo]
val aHList = g.to(base)
val bHList = g.to(update)

aHList
  .zipWithIndex
  .map({
    case (l: List, i: Int) => l ++ bHList(i)
    case (o: Option, i: Int) => if (!bHList(i).nonEmpty) {
      updateHList(i)
    } else {
      o
    }
    case (_, i: Int) => updateHList(i)
  })
Run Code Online (Sandbox Code Playgroud)

但事实证明,泛型.to方法不输出 …

scala shapeless

2
推荐指数
1
解决办法
906
查看次数

具有自定义类型绑定的无形映射和子类型多态

试图映射自定义多态类的HList我得到了可怕的"无法找到参数映射器的隐式值"错误.代码示例:

import shapeless._

trait SubTrait
case class A() extends SubTrait
case class B() extends SubTrait

case class C[T <: SubTrait](x: T)

object TheMapper extends Poly1 {
  implicit def default[T <: SubTrait, L[T] <: C[T]] = at[L[T]](_.x)
}

val ab = C(A()) :: C(B()) :: HNil

println(ab.map(TheMapper))
Run Code Online (Sandbox Code Playgroud)

如果L [T]的边界是例如Iterable(参见这个非常相似的问题,解决方案和注释),这可以正常工作.我错过了什么?

polymorphism scala shapeless

2
推荐指数
1
解决办法
76
查看次数