标签: shapeless

HList上的映射在Scala&Shapeless中失败,具有泛型类型的子类型

假设我们有以下类和一些值(在Scala中):

class A[T](val x: T)
class B[T](x: T, val y: T) extends A[T](x)

val x1 = new A("test")
val x2 = new B(1,2)
val x3 = new B("foo","bar")
val x4 = new A(1)
Run Code Online (Sandbox Code Playgroud)

此外,我们定义以下多态函数值(使用无形):

object f extends (A ~> Option) {
  def apply[T](s: A[T]) = Some(s.x)
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以致电:

f(x1); f(x2); f(x3); f(x4)
Run Code Online (Sandbox Code Playgroud)

哪一切都成功了(应该恕我直言).然而:

val list = x1 :: x2 :: x3 :: x4 :: HNil
list.map(f)

// could not find implicit value for parameter mapper:
// shapeless.Mapper[f.type,shapeless.::[A[String],shapeless.::[
//   B[Int],shapeless.::[B[String],shapeless.::[A[Int],shapeless.HNil]]]]]
Run Code Online (Sandbox Code Playgroud)

我期待的地方: …

scala shapeless

9
推荐指数
1
解决办法
1093
查看次数

什么是Case.Aux无形

我对无形特征概述中显示的示例感到困惑.

object size extends Poly1 {
  implicit def caseInt = at[Int](x => 1)
  implicit def caseString = at[String](_.length)
  implicit def caseTuple[T, U]
    (implicit st : Case.Aux[T, Int], su : Case.Aux[U, Int]) =
      at[(T, U)](t => size(t._1)+size(t._2))
}

scala> size(((23, "foo"), 13))
res7: Int = 5
Run Code Online (Sandbox Code Playgroud)
  1. 什么是Case.Aux?
  2. 为什么参数化类型是Int not String
  3. 如果size(((23,"foo",123),13)),如何定义CaseTuple?

提前谢谢了

scala shapeless

9
推荐指数
1
解决办法
1008
查看次数

为无形记录定义类型类

我正在尝试学习Shapeless,我想定义一个monoid,它将无形记录的实例加在一起.请注意,我使用的是algebird monoids(不是scalaz),但我确信它们非常相似.以下是我希望能够做到的一个例子:

val result = Monoid.sum(
  ('a ->> 1) :: ('b ->> 1) :: HNil,
  ('a ->> 4) :: ('b ->> 3) :: HNil,
  ('a ->> 2) :: ('b ->> 6) :: HNil)
// result should be: ('a ->> 7) :: ('b ->> 10) :: HNil
Run Code Online (Sandbox Code Playgroud)

我想出了如何为HList编写monoid实例,如下所示:

  implicit val HNilGroup: Group[HNil] = new ConstantGroup[HNil](HNil)
  implicit val HNilMonoid: Monoid[HNil] = HNilGroup
  class HListMonoid[H, T <: HList](implicit hmon: Monoid[H], tmon: Monoid[T]) extends Monoid[::[H, T]] {
    def zero = hmon.zero :: tmon.zero
    def …
Run Code Online (Sandbox Code Playgroud)

scala record typeclass shapeless

9
推荐指数
1
解决办法
417
查看次数

HList的证据保留LUB约束

我想我需要一个受限制的HList,它的所有元素都是某种类型的子类型.LUBConstraint似乎是我想要的,事实上它确实限制了这样一个HList 的构造 - 但是我看不出如何再次获取证据,所以我可以映射(实际上,遍历,因为它需要是monadic)在HList上并调用每个元素上的方法(存在于LUB类型中).

另外,我希望从遍历操作得到的HList的类型与输入HList的类型完全相同.

用例是一种功能性的"监听器列表" - HList的所有元素都是"监听器",必须通知"事件",接受或拒绝它们,并返回更新的"内部状态"的新版本.如果这就是我所需要的,那么我可以使用普通的不可变Scala集合.但我也希望直接键入单个元素而不使用asInstanceOf- 因此尝试使用HList的动机.

scala hlist shapeless

9
推荐指数
1
解决办法
425
查看次数

无形HList类型检查

我正在使用Shapeless并使用以下方法计算两个HLists之间的差异:

  def diff[H <: HList](lst1: H, lst2:H):List[String] = (lst1, lst2) match {
    case (HNil, HNil)                 => List()
    case (h1::t1, h2::t2) if h1 != h2 => s"$h1 -> $h2" :: diff(t1, t2)
    case (h1::t1, h2::t2)             => diff(t1, t2)
    case _                            => throw new RuntimeException("something went very wrong")
  }
Run Code Online (Sandbox Code Playgroud)

由于该方法的两个参数都采用了H,我希望不同类型的HLists不能在这里编译.例如:

diff("a" :: HNil, 1 :: 2 :: HNil)
Run Code Online (Sandbox Code Playgroud)

不应该编译,但确实如此,它会产生运行时错误:java.lang.RuntimeException: something went very wrong.我可以对类型参数做些什么来使这个方法只接受相同类型的两个边?

scala type-level-computation shapeless

9
推荐指数
2
解决办法
1216
查看次数

"内联"val后出现奇怪的类型错误

我正在观察一个非常奇怪的类型错误shapeless.everywhere.考虑下面的菊石脚本加载正常load.module:

load.ivy("com.chuusai" %% "shapeless" % "2.3.0")

@

import shapeless._
import poly._

final case class Person(name: Person.Name, age: Person.Age)

object Person {
  final case class Name(value: String) extends AnyVal
  final case class Age(value: Int) extends AnyVal
}

def happyBirthday(person: Person, howManyYearsPast: Int): Person = {
  object incAge extends ->((age: Int) => age + howManyYearsPast)
  // THE MAGIC VAL
  val oldPerson = everywhere(incAge)(person)
  oldPerson
}

val john = Person(Person.Name("John Doe"), Person.Age(42))

val oldJohn = happyBirthday(john, 30)
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试MAGIC …

scala shapeless

9
推荐指数
1
解决办法
180
查看次数

过滤器使用无形,Scala

HList按类型过滤很容易:

val hlist = 1 :: 2 :: "3" :: true :: false :: HNil
hlist.filter[Int]
Run Code Online (Sandbox Code Playgroud)

但是如何制作我的自定义类型过滤器?我想要那样的smth:例如我得到了一些函数的列表:

def function1(s: String) = s.toInt
def function2(s: String) = s.toDouble
def function3(i: Int) = i.toDouble

val hflist = function1 _ :: function3 _ :: function2 _ :: HNil

hflist customFilter[String] //> function1 _ :: function2 _ :: HNil
Run Code Online (Sandbox Code Playgroud)

因此,在使用此过滤器之后,String将构造从类型到其他类型的函数列表.

我有一个想法,为此使用地图,但它没有成功.

有关我的评论的更多信息:

我试图在地图上测试这个想法:

所以,如果我有一些列表(让我们使用hlist&hflist):

object allFunction extends Poly1 {
  implicit def default[T, M] =
    at[T => …
Run Code Online (Sandbox Code Playgroud)

scala list filter heterogeneous shapeless

8
推荐指数
1
解决办法
1236
查看次数

查找Shapeless HList的类型类实例

假设我有Show[T]Scalaz中的特征:https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Show.scala#L9

我也有一个无形的HList,可能看起来像"1" :: 2 :: 3L :: HNil.

有没有办法找到Show每个元素的实例并应用shows这样我最终"1" :: "2" :: "3L" :: HNil

如果任何元素的类型Show在范围内没有隐式实例,我会想要编译错误.

我认为,如果我建立一个HList对的Show情况下,我应该能够用zipApply得到HList我想要的,但我不知道是否有一种方式来获得具有斯卡拉推断HListShow实例,而不是我建起来的手.

scala hlist shapeless

8
推荐指数
1
解决办法
669
查看次数

如何在无形中你说证明是空类型(即假的)

我想编写一个以Nat为参数的函数,并且如果此nat不能被3整除,则返回此nat.

例如 :

def myFunction[N <: Nat](n :N)(implicit ev: /* what do I put here that say not divible by 3 ? */): N = n
Run Code Online (Sandbox Code Playgroud)

要做到这一点,我必须写一些说"N不能被_3整除"的东西,或者"Mod.Aux [N,_3,_0]是空类型"

我怎么能在无形的情况下做到这一点?

scala shapeless

8
推荐指数
1
解决办法
394
查看次数

解码无形标记类型

鉴于以下关于亚扪人:

@ import $ivy.`io.circe::circe-core:0.9.0` 

@ import $ivy.`io.circe::circe-generic:0.9.0`                   

@ import $ivy.`com.chuusai::shapeless:2.3.3` 

@ import shapeless.tag 
import shapeless.tag

@ trait Foo 
defined trait Foo

@ import io.circe._, io.circe.generic.semiauto._ 
import io.circe._, io.circe.generic.semiauto._

@ import shapeless.tag.@@ 
import shapeless.tag.@@
Run Code Online (Sandbox Code Playgroud)

然后,我尝试定义通用标记类型解码器:

@ implicit def taggedTypeDecoder[A, B](implicit ev: Decoder[A]): Decoder[A @@ B] = 
    ev.map(tag[B][A](_)) 
defined function taggedTypeDecoder
Run Code Online (Sandbox Code Playgroud)

它在明确拼写时有效String @@ Foo:

@ val x: String @@ Foo = tag[Foo][String]("foo") 
x: String @@ Foo = "foo"

@ implicitly[Decoder[String @@ Foo]] 
res10: Decoder[String @@ Foo] = io.circe.Decoder$$anon$21@2b17bb37
Run Code Online (Sandbox Code Playgroud)

但是,在定义类型别名时:

@ …
Run Code Online (Sandbox Code Playgroud)

scala shapeless circe

8
推荐指数
1
解决办法
820
查看次数