标签: shapeless

HList/KList是否适合作为方法参数?怎么参考?输入清单?

我发现了HList/KList,它们非常酷.我有一个实际的用例,其中具有保守类型信息的异构类型和可变长度容器将非常有用(更多信息,请参见下面的背景).但是,我还没有将H/KList的用法理解为方法参数,在这里我被迫完全键入 - 注释参数或松散类型信息.H/KLists甚至可以用作参数,如果完整类型当然不知道?如何在不丢失类型信息的情况下引用H/KList?

"类型列表"可以用来指代异构和可变长度类型参数的元组吗?在这里它说: ... the types of the elements can be tracked separate from the actual element values. To do this we create an purely abstract type (it has no instances) which models a list of types, let's call it TList. 我玩了它,但还没有理解如何使用它作为参数的类型注释HList.

基本上,我想要这样的东西:

implicit def hlistToTypedLink[TL](a: HList[TL]):TypedLink[TL] = new TypedLink[TL](a.map(a:X => new TypedHandle[X]))
Run Code Online (Sandbox Code Playgroud)

其中TL指的是Type List,X指的是当前元素的类型.所以这里的HList应该映射到另一个类似于Tuple的容器TypedLink,由类型列表TL进行参数化.元素将被包装在另一个参数化容器TypedHandle中,使用当前类型X键入.

这可能吗?

我看到了Shapeless的'HList及其"统一"方法,但问题仍然存在:除了可变长度之外,我不知道如何在参数列表中引用它.

我的第二个希望是使用KList.它适用于我的情况,因为TypedHandle是具有相同构造函数的公共容器.随着KLIST它似乎更容易输入注释,根据apocalisp:

 val m = List(1, 2, 3, 4) :^: List("str1", "str2") :^: KNil
Run Code Online (Sandbox Code Playgroud)

将是类型:

 KCons[Int,java.lang.String :: HNil,List]
Run Code Online (Sandbox Code Playgroud)

但问题仍然存在:在方法定义中,我不知道它是否会是一个 …

scala typelist hlist shapeless klist

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

异构映射,编译时的依赖类型

试图通过Miles Sabin 使用这个技巧来创建一个只接受一组预定义参数的函数types.

val bool =  Boolean
val timestamp = new Timestamp(date.getTime())
val str = "My String"
Run Code Online (Sandbox Code Playgroud)

然后跟随应该在编译时通过

takeValue(bool)
takeValue(timestamp)
takeValue(str)
Run Code Online (Sandbox Code Playgroud)

这里takeValue应该失败takeValue(someIntValue),如果implicit用于type Int不defined.And这种故障会在编译的时候.

trait MyConv[K] { type V; def convert: AnyRef => V }

def iMakeConv[V0](con: AnyRef => V0) = new MyConv[con.type] {
  override type V = V0
  val convert = con
}

  def takeValue(value:AnyRef)(implicit conv :MyConv[value.type]) : \/[Throwable,conv.V] = \/.fromTryCatch(conv.convert(value))
Run Code Online (Sandbox Code Playgroud)

然后

implicit val strAny = iMakeConv((x:Any) …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

在Shapeless中,我可以为非案例类提供一个`LabelledGeneric`实例,它将启用类型类实例的自动派生吗?

我有一个json库,它通过遵循Scala中的类型类模式来定义(定义如何读取json)的概念 ReadCodec.该库使用Shapeless ' Typeclass构造来免费为任何案例类派生自动实例 ReadCodec.

现在,我有一个代码生成器,它在Scala生成的类不是case类(但可能应该是).我可以让代码生成器为每个类生成ReadCodec实例,这就是我们现在所拥有的.但是现在如果我希望生成的类支持一些新的序列化形式,我需要修改代码生成以输出这个新类型类的实例.

有没有办法可以修改代码生成器来输出具有实例 LabelledGeneric或其他东西的类,这些实例可以利用生成(通过宏)案例类自动实例的机制?这样,生成的代码可以与使用Shapeless'的任何类型类模式互操作以Typeclass实现实例.

code-generation scala typeclass shapeless

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

从Shapeless HList到case类的转换时缺少Implicit Generic.Aux

我刚刚开始学习scala,今天我决定编写一个CSV解析器,它可以很好地加载到case类中,但是将数据存储在Shapeless的HList对象的行(列表)中,这样我就可以接触到类型级编程了.

这是我到目前为止所拥有的:

// LoadsCsv.scala

import shapeless._
import scala.collection.mutable

trait LoadsCsv[A, T <: HList] {

    val rows: mutable.MutableList[T] = new mutable.MutableList[T]

    def convert(t: T)(implicit gen: Generic.Aux[A, T]): A = gen.from(t)

    def get(index: Int): A = {
        convert(rows(index))
    }

    def load(file: String): Unit = {
        val lines = io.Source.fromFile(file).getLines()
        lines.foreach(line => rows += parse(line.split(",")))
    }

    def parse(line: Array[String]): T

}
Run Code Online (Sandbox Code Playgroud)

并且正在加载数据集的对象:

// TennisData.scala

import shapeless._

case class TennisData(weather:String, low:Int, high:Int, windy:Boolean, play:Boolean)

object TennisData extends LoadsCsv[TennisData, String :: Int :: Int :: …
Run Code Online (Sandbox Code Playgroud)

scala type-level-computation shapeless

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

Scala无形:从Mapper派生类型

该方法doesNotCompile仅接受仅包含Label[A]条目的HLists .有一个Mapper可以将Label [A]转换为String(准确地说:) Const[String]#?.但是,当我应用映射器时,返回类型为ev1.Out.我知道这实际上只是一个只有字符串的HList,但我怎么能说服编译器呢?

import shapeless._
import shapeless.poly._
import shapeless.ops.hlist._
import shapeless.UnaryTCConstraint._

object Util {
  case class Label[A](name: String, value: A)

  object GetLabelName extends (Label ~> Const[String]#?) {
    def apply[A](label: Label[A]) = label.name
  }
}

object Main {
  import Util._

  def bar(l: List[String]) = ???

  def compiles = {
    val names = "a" :: "b" :: HNil
    bar(names.toList)
  }

  // A is an HList whose members are all Label[_]
  def doesNotCompile[A <: HList : *->*[Label]#?](labels: …
Run Code Online (Sandbox Code Playgroud)

scala implicits shapeless

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

使用默认值映射HList

http://scastie.org/22713

本地副本:

/***
scalaVersion := "2.11.8"
addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.7.1")
libraryDependencies ++= {
  val shapelessVersion = "2.2.5"
  Seq(
    "com.chuusai" %% "shapeless" % shapelessVersion
  )
}
*/

import shapeless._

case class Foo()

trait Wrapper

case class S(s: String) extends Wrapper
case class I(i: Int) extends Wrapper

object Main extends App {
  object wrap extends Poly1 {
    implicit def caseString = at[String](S.apply)
    implicit def caseInt = at[Int](I.apply)
    implicit def caseOther[T] = at[T](identity)
  }

  type A = Foo :: String :: HNil …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

使用Circe将包含HList的案例类解析为JSON字符串

我在Scala做的事情.我有以下案例类:

import shapeless._
case class Foo(param1: String, param2: HList)
Run Code Online (Sandbox Code Playgroud)

我想使用Circe获得这种类型的JSON表示.我还想将生成的JSON字符串映射回类型.

模块circe-shapes自动推导出HLists,并且很容易从HList到JSON再返回.看这个例子:

scala> import shapeless._
import shapeless._

scala> import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
import io.circe._
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._

scala> import io.circe.shapes._
import io.circe.shapes._

scala> val myList = 30 :: "car" :: HNil
myList: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 30 :: car :: HNil

scala> val listJson = myList.asJson
listJson: io.circe.Json =
[
  30,
  "car"
]

scala> listJson.as[HList] // won't work
<console>:32: error: could not …
Run Code Online (Sandbox Code Playgroud)

json scala hlist shapeless circe

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

无形'延迟和默认参数导致隐式解析失败

我的一个项目使用scala功能混合,看起来不能很好地混合在一起:

  • 类型类和无形自动类型类实例派生
  • 隐式转换(为具有类型类实例的类型添加有用的语法)
  • 默认参数,因为即使它们通常是一件坏事,它们在这里也太方便了

我遇到的问题是类型类实例派生失败,如果:

  • 未明确指定默认参数
  • 无形推导用途 Lazy

这是我可以编写的用于重现问题的最小代码量:

Show.scala

import shapeless._

trait Show[A] {
  def show(a: A): String
}

object Show {
  def from[A](f: A => String): Show[A] = new Show[A] {
    override def show(a: A) = f(a)
  }

  implicit val intShow: Show[Int] = Show.from(_.toString)

  implicit def singletonShow[A](implicit
    sa: Show[A]
  ): Show[A :: HNil] = Show.from { 
    case (a :: HNil) => sa.show(a)
  }

  implicit def singletonCaseClassShow[A, H <: HList](implicit
    gen: Generic.Aux[A, H],
    sh: Lazy[Show[H]]
  ): Show[A] = Show.from …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

Shapeless是否使用反射并且在scala生成代码中使用是否安全?

在阅读了很多文章后,我仍然对scala Shapeless库感到困惑.似乎Shapeless使用scala编译功能?那么它是否使用反射并且对生产代码安全吗?

reflection scala shapeless

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

在scala中的类型级别模式匹配

理想情况下,我想在Scala中的类型级别编写Haskell样式模式匹配,如下所示:

无形可以用于这样的事情吗?

object Test{


  type F[Int] = String
  type F[Boolean] = Int  // but this line does not compile

  implicitly[String =:= F[Int]]
  implicitly[Int =:= F[Boolean]]

}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,如果F需要Int则返回String,如果需要Boolean则返回Int.

澄清(基于这个答案)

以下是我想在函数和类型类中使用这些类型的方法:

  abstract class WrappedF[T] {
    type F
    type Unwrap = T
  }

  type F[X <: WrappedF[_]] = X#F

  class IntF      extends WrappedF[Int]     { type F = StringF }
  class BooleanF  extends WrappedF[Boolean] { type F = IntF }
  class StringF …
Run Code Online (Sandbox Code Playgroud)

types scala pattern-matching type-level-computation shapeless

3
推荐指数
2
解决办法
226
查看次数