浏览无形代码,我在{} 这里和这里看到了看似无关紧要的代码:
trait Witness extends Serializable {
type T
val value: T {}
}
trait SingletonOps {
import record._
type T
def narrow: T {} = witness.value
}
Run Code Online (Sandbox Code Playgroud)
我几乎忽略了它作为一个错字,因为它什么也没做,但显然它做了一些事情.看到这个提交:https://github.com/milessabin/shapeless/commit/56a3de48094e691d56a937ccf461d808de391961
我不知道它做了什么.谁能解释一下?
我现在已经做了一些HList的实现.一个基于丹尼尔斯皮瓦克在斯卡拉之地的高级巫术讲话,另一个基于Apocalisp博客中的帖子.目标是有一个异类列表,其中主要类型不是异质的,而是更高类型.例如:
val requests = Request[String] :: Request[Int] :: HNil
Run Code Online (Sandbox Code Playgroud)
我可以在列表中执行映射来执行请求,并生成更高类型的异构列表.所以:
requests.map(execute)
Run Code Online (Sandbox Code Playgroud)
应该相等
String :: Int :: HNil
Run Code Online (Sandbox Code Playgroud)
可悲的是,我的所有尝试都产生了任何HList.以下是最近尝试的代码:
class Request[+Out](o:Out) {
type O = Out
def v:O = o
}
object HList {
trait Func[-Elem,Out] {
type Apply[E <: Elem] <: Out
def apply[N <: Elem](e:N):Apply[N]
}
sealed trait HList[Base] {
type Head <: Base
type Tail <: HList[Base]
type Map[Out,F <: Func[Base,Out]] <: HList[Out]
def head:Head
def tail:Tail
def ::[A <: Base](a:A):HList[Base]
def map[Out,F <: Func[Base,Out]](f:F):Map[Out,F]
}
case class …Run Code Online (Sandbox Code Playgroud) 我有一个元组,想要添加一个元素而不会失去类型安全性.这就是我想要实现的目标:
val tuple = ("", 1, 1f) // (String, Int, Float)
val newTuple:(String, Int, Float, Double) = tuple :+ 1d
Run Code Online (Sandbox Code Playgroud) 我想了解Scala中的polytypic概念,我遇到了无形库,这将是学习和应用无形的最佳起点.
我试图了解它是如何Generic工作的(也是TypeClass如此).github wiki在示例和文档上非常稀少.是否有一个规范的博客/文档页面描述Generic和TypeClass详细?
具体来说,这两种方法有什么区别?:
def find1[T](implicit gen: Generic[T]): Generic[T] = gen
def find2[T](implicit gen: Generic[T]): Generic[T] { type Repr = gen.Repr } = gen
Run Code Online (Sandbox Code Playgroud)
特定
object Generic {
type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }
def apply[T](implicit gen: Generic[T]): Aux[T, gen.Repr] = gen
implicit def materialize[T, R]: Aux[T, R] = macro GenericMacros.materialize[T, R]
}
Run Code Online (Sandbox Code Playgroud) 我昨晚熬夜试图弄清楚这个无形的问题,如果我不把它从胸前拿走,我担心它会吃掉我的晚上,所以这里就是这样.
在这个最小化版本中,我只是定义了一个类型类,它将递归转换为异构列表:
import shapeless._
trait DeepHLister[R <: HList] extends DepFn1[R] { type Out <: HList }
trait LowPriorityDeepHLister {
type Aux[R <: HList, Out0 <: HList] = DeepHLister[R] { type Out = Out0 }
implicit def headNotCaseClassDeepHLister[H, T <: HList](implicit
dht: DeepHLister[T]
): Aux[H :: T, H :: dht.Out] = new DeepHLister[H :: T] {
type Out = H :: dht.Out
def apply(r: H :: T) = r.head :: dht(r.tail)
}
}
object DeepHLister extends LowPriorityDeepHLister {
implicit …Run Code Online (Sandbox Code Playgroud) 我正在考虑做类似于安全地复制不同类型的案例类之间的字段但使用重新排序的字段,即
case class A(foo: Int, bar: Int)
case class B(bar: Int, foo: Int)
Run Code Online (Sandbox Code Playgroud)
我想有东西转A(3, 4)成B(4, 3)-不成形LabelledGeneric浮现在脑海,但是
LabelledGeneric[B].from(LabelledGeneric[A].to(A(12, 13)))
Run Code Online (Sandbox Code Playgroud)
结果是
<console>:15: error: type mismatch;
found : shapeless.::[shapeless.record.FieldType[shapeless.tag.@@[Symbol,String("foo")],Int],shapeless.::[shapeless.record.FieldType[shapeless.tag.@@[Symbol,String("bar")],Int],shapeless.HNil]]
(which expands to) shapeless.::[Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("foo")],Int],shapeless.::[Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],Int],shapeless.HNil]]
required: shapeless.::[shapeless.record.FieldType[shapeless.tag.@@[Symbol,String("bar")],Int],shapeless.::[shapeless.record.FieldType[shapeless.tag.@@[Symbol,String("foo")],Int],shapeless.HNil]]
(which expands to) shapeless.::[Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],Int],shapeless.::[Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("foo")],Int],shapeless.HNil]]
LabelledGeneric[B].from(LabelledGeneric[A].to(A(12, 13)))
^
Run Code Online (Sandbox Code Playgroud)
如何重新排序记录中的字段(?),这样可以使用最少的样板?
感谢@ MilesSabin的回答,我可以编写一个类型级的Fibonacci序列:
sealed trait Digit
case object Zero extends Digit
case object One extends Digit
sealed trait Dense { type N <: Dense }
sealed trait DNil extends Dense { type N = DNil }
case object DNil extends DNil
final case class ::[+H <: Digit, +T <: Dense](digit: H, tail: T) extends Dense {
type N = digit.type :: tail.N
}
/* The `A`th Fibonacci number is `B` */
trait Fib[A <: Dense, B <: Dense]
object …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习Shapeless(使用版本2.10.2).我创建了一个非常简单的可扩展记录:
val rec1 = ("foo" ->> 42) :: HNil
根据REPL,这有类型
shapeless.::[Int with shapeless.record.KeyTag[String("foo"),Int],shapeless.HNil]
我试图定义一个简单的函数:
def fun(x: ::[Int with KeyTag[String("foo"), Int], HNil]) = x("foo")
Run Code Online (Sandbox Code Playgroud)
但它甚至没有编译.我不能在类型声明中使用String("foo"),并得到错误.
我有两个问题:
编辑
我发现:
val rec1 = ("foo" ->> 42) :: HNil
val rec2 = ("foo" ->> 43) :: HNil
var x = rec1
x = rec2
Run Code Online (Sandbox Code Playgroud)
效果很好.我得出结论rec1,rec2和x属于同一类型.我只是不知道如何在代码中表达该类型!
这里的问题是关于将案例类映射到Map [String,Any].我想知道相反的方法是什么,将Map [String,Any]转换为case类.给出以下地图:
val mp = Map("name" -> "Tom", "address" -> Map("street" -> "Jefferson st", "zip" -> 10000))
Run Code Online (Sandbox Code Playgroud)
将其转换为以下案例类Person:
case class Person(name:String, address:Address)
case class Address(street:String, zip:Int)
val p = Person("Tom", Address("Jefferson st", 10000))
Run Code Online (Sandbox Code Playgroud)
用这样的东西:
val newP = mp.asCC[Person]
assert(newP.get == p)
Run Code Online (Sandbox Code Playgroud)
我应该如何使用Shapeless.