标签: shapeless

如何使用 LabelledGeneric 一般更新案例类字段?

使用 shapeless,可以LabelledGeneric像这样更新 case 类字段:

case class Test(id: Option[Long], name: String)
val test = Test(None, "Name")
val gen = LabelledGeneric[Test]

scala> gen.from(gen.to(test) + ('id ->> Option(1L)))
res0: Test = Test(Some(1),Name)
Run Code Online (Sandbox Code Playgroud)

我希望Test类(和其他类)扩展一个抽象类Model,该类将实现一个方法withId,该方法将使用LabelledGeneric类似于上述代码来更新id字段,如果它有一个(它应该)。

我的尝试将 a 的隐式参数添加LabelledGeneric[A]到 的构造函数中Model,它实现得很好。我还需要以某种方式为LabelledGeneric#Repr具有id要替换的字段的记录语法提供证据。添加一个隐式Updater参数来withId满足编译器,这样下面的代码会编译,但它不可用。

import shapeless._, record._, ops.record._, labelled._, syntax.singleton._, tag._

abstract class Model[A](implicit gen: LabelledGeneric[A] { type Repr <: HList }) { this: A => …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

通用[A]其中A是一个类?

使用Shapeless,我试图获得一个Generic[F]通道:

import shapeless._

class F(x: Int)
Run Code Online (Sandbox Code Playgroud)

但它失败了:

scala> Generic[F]
<console>:20: error: could not find implicit value for parameter gen: shapeless.Generic[F]
       Generic[F]
              ^
Run Code Online (Sandbox Code Playgroud)

可以无形生产Generic[F]?如果是这样,怎么样?

scala shapeless

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

斯卡拉.如何创建接受不同arities的元组的通用方法?

在我的应用程序中,我有很多地方,我需要获取元组列表,groupBy它由元组的第一个元素,并从其余元素中删除.例如,我有元组

(1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"), and result should be Map(1 -> List(("Joe", "Account"), ("Joe", "Account")), 2 -> List(("John", "Account")))
Run Code Online (Sandbox Code Playgroud)

它很容易实现

data.groupBy(_._1).map { case (k, v) => k -> v.map(f => (f._2, f._3)) }
Run Code Online (Sandbox Code Playgroud)

但我正在寻找一般的解决方案,因为我可以有不同的元素,2,3,4或甚至7的元组.我认为Shapeless或Scalaz可以帮助我,但我在这些库中的经验很少,请指出一些例子

scala scalaz shapeless

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

通过Shapeless获取默认的case类参数

shapeless是否提供了一个类型类/宏来召唤一个HList包含案例类所有参数的默认值?

假设我们有这个案例类:

case class User(name: String, age: Int = 18)
Run Code Online (Sandbox Code Playgroud)

然后我想得到这样一个HList:

None :: Some(() => 18) :: HNil
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

HList 的无形类型推断不起作用

我正在尝试实现用于获取第一个元素的通用函数:

import shapeless.ops.hlist.IsHCons
import shapeless.{Generic, HList}

object App {

  def main(args : Array[String]) {
    val a: Int = getFirst((1, 2, 3))
    val b: String = getFirst(("a", "b", 10, 45, "aaa"))
  }

  def getFirst[A, Head, Repr <: HList, Tail <: HList](input: A)
                                                     (implicit hcons: IsHCons.Aux[Repr, Head, Tail],
                                                      gen: Generic.Aux[A, Repr]): Head = gen.to(input).head
}
Run Code Online (Sandbox Code Playgroud)

问题是编译器无法正确推断Repr并将Tail它们设置为Nothing. 就这个:

Error:(9, 26) could not find implicit value for parameter gen: shapeless.Generic.Aux[(Int, Int, Int),Repr]
    val a: Int = getFirst((1, 2, …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala generic-programming type-level-computation shapeless

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

Shapeless 的“分配财产”

不确定正确的术语是否是“分配财产”,但我记得在学校学过这个,所以这里是我想做的一个例子:

鉴于:

type MyHList = (A :+: B :+: C :+: CNil) :: (Foo :+: Bar :+: CNil) :: HNil
Run Code Online (Sandbox Code Playgroud)

Shapeless 中是否有任何内置类型类可以解决这个问题:

type Out = (A, Foo) :+: (A, Bar) :+: (B, Foo) :+: (B, Bar) :+: (C, Foo) :+: (C, Bar) :+: CNil
Run Code Online (Sandbox Code Playgroud)

谢谢

scala cartesian-product hlist shapeless coproduct

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

Scala联合类型与闭包

我正在尝试在Miles Sabin的博客文章中定义的Scala的联合类型:

http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/

并在中讨论过

如何定义"类型析取"(联合类型)?

对于那里定义的简单情况,它们工作正常,但我要做的是使用它们在Play Framework中创建一个只接受某些值(String,Boolean,Int,Undefined)的通用JSON解析器,然后成功传递它们.

这是我的代码:

type UpdateType = Option[String] |?| Option[Int] |?| Option[Boolean] |?| Option[List[Int]]

def withValue[T : (UpdateType)#?](request: Request[JsValue])(block: (String, T) => Future[SimpleResult]) = {
  val field = request.body \ ("field")
  val value = request.body \ ("value")
  (field, value) match {
    case (x: JsString, y: JsString) => block(x.value.toString, Some(y.value.toString))
    case (x: JsString, y: JsNumber) => block(x.value.toString, Some(y.value.intValue))
    case (x: JsString, y: JsBoolean) => block(x.value.toString, Some(y.value.booleanValue))
    case (x: JsString, y: JsUndefined) => block(x.value.toString, None)
    case _ => …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

将列表转换为案例类

作为一个练习,我试图看看我是否可以List[Any]使用无形的方法将其"投射"到案例类中.

我想要实现的一个非常基本的例子:

case class Foo(i: Int, j: String)
val foo: Option[Foo] = fromListToCaseClass[Foo]( List(1:Any, "hi":Any) ) 
Run Code Online (Sandbox Code Playgroud)

以下是我如何塑造我的解决方案(这可能非常不合适):

def fromListToCaseClass[CC <: Product](a: List[Any]): Option[CC] = a.toHList[???].map( x => Generic[CC].from(x) )
Run Code Online (Sandbox Code Playgroud)

这是我的推理:

我知道你可以从case类转到HList [T](CC - > HList [T]); 其中T是HList的类型.我也知道你可以从列表中创建一个HList(list - > Option [HList]),只要你知道HList的类型.最后我知道你可以从HList转到案例类(HList - > CC).

CC -> HList[T]
list -> Option[HList[T]] -> Option[CC]
Run Code Online (Sandbox Code Playgroud)

我想知道这是否有意义,或者我是否离开这里.我们能做到这一点吗?还有其他建议吗?谢谢!

scala shapeless

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

在无形Coproduct上进行模式匹配的清洁方式

我发现了两种可以在无形副产品上进行模式匹配的方法.我也搜索了这个主题并找到了这个

import shapeless._

object ShapelessEx3 extends App {
   case class Red()
   case class Green()
   case class Blue()
   type Colors = Red :+: Green :+: Blue :+: CNil
   val blue = Coproduct[Colors](Blue())
   val green = Coproduct[Colors](Green())
   printColor1(blue)
   printColor2(green)

   def printColor1(c: Colors) : Unit = {
      (c.select[Red], c.select[Green], c.select[Blue]) match {
         case (Some(_), None, None) => println("Color is red")
         case (None, Some(_), None) => println("Color is green")
         case (None, None, Some(_)) => println("Color is blue")
         case _ => println("unknown color")
      } …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

Scala:抽象案例类的toString函数

假设我有一个case类定义如下:

case class User(name: String, age: Int)
Run Code Online (Sandbox Code Playgroud)

我想像这样重写它的toString方法:

 case class User(name: String, age: Int) {
    override def toString: String = 
      s"name = $name
        age = $age"
Run Code Online (Sandbox Code Playgroud)

这样,如果我跑步print(user.toString),我会得到:

name = nameOfUser
age = ageOfUser
Run Code Online (Sandbox Code Playgroud)

现在我有另一个类Computer,它被定义为

case class Computer(make: String, RAM: int, clockSpeed: Double)
Run Code Online (Sandbox Code Playgroud)

我想为所有值打印相同的内容。我想要类似的东西:

  make = makeOfComputer
  RAM = RAMOfComputer
  clockSpeed = speedOfComputer
Run Code Online (Sandbox Code Playgroud)

与其将上面的toString函数复制,粘贴和调整到Computer该类中,不如将其抽象化,以便任何case类都可以使用它。

我有一些想法可以使用

 CaseClassType.unapply(caseClassInstance).get.productIterator.toList
Run Code Online (Sandbox Code Playgroud)

获取案例类的值,并

 classOf[CaseClass].getDeclaredFields.map(_.getName)
Run Code Online (Sandbox Code Playgroud)

获取字段名称。这意味着我可以在不知道案例类的实际结构的情况下,找到案例类中所有值的列表以及所有字段名称的列表。

一旦有了这两个集合,就可以递归地遍历它们来创建字符串。我在想像下面这样的东西可以工作,但是不幸的是,scala不允许案例类继承自其他案例类。

case class StringifiableCaseClass(){
  override def toString: String =
     //get the values …
Run Code Online (Sandbox Code Playgroud)

inheritance scala typeclass case-class shapeless

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

为什么不将函数定义为单例函数?

考虑在无形状回购中找到的单例函数的定义:

/** Polymorphic function selecting an arbitrary element from a non-empty `Set`. */
object choose extends (Set ~> Option) {
  def apply[T](s : Set[T]) = s.headOption 
}
Run Code Online (Sandbox Code Playgroud)

def在以下示例中,将其与传统语法进行对比:

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)

package utils

object isSatisfyingSomePredicate extends (Foo => Boolean) {
  def apply(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)

注意呼叫站点现在如何变成

isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

代替

UtilWithASingleMethod.isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

要么

import UtilWithASingleMethod._

isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

就个人而言,UtilWithASingleMethod软件包似乎只是为了能够使用熟悉的def语法而没有添加任何有用的信息。

除了主观的缺点(例如不熟悉或与工厂模式中使用的对象+应用样式混淆)之外,单例函数定义还有其他技术缺点吗?

singleton scala package shapeless function-definition

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

为什么Scala编译器可以提供隐式的out of object,但不能提供inside?

标题可能很模糊,但这是代码: https: //github.com/amorfis/why-no-implicit

所以有一个工具可以转化Map[String, Any]为简单的案例类。测试通过了,这段代码说明了它的全部内容:

        case class TargetData(
          groupId: String,
          validForAnalysis: Boolean,
          applicationId: Int
        )

        val map = Map(
          "groupId" -> "123456712345",
          "applicationId" -> 31,
          "validForAnalysis" -> true
        )

        val transformed: TargetData = MapDecoder.to[TargetData](map).transform
Run Code Online (Sandbox Code Playgroud)

这段代码有效。当提供简单的情况时,它很好地创建了案例类实例map

但是,该transform方法必须在“外部”调用 - 就像示例中一样。当我尝试将其移至该MapDecoder.to方法时 - 编译器抱怨缺少隐式。

所以我将代码更改MapDecoder.to为:

def to[A](map: Map[String, Any]) = new MapDecoderH[A](map)
Run Code Online (Sandbox Code Playgroud)

对此:

def to[A](map: Map[String, Any]) = new MapDecoderH[A](map).transform
Run Code Online (Sandbox Code Playgroud)

它停止工作了。这是为什么?为什么在一种情况下提供了隐含的内容,而在另一种情况下则没有提供?所有的变化是我想transform在其他地方调用该方法以MapDecoder.to返回案例类而不是某个转换器。

更新:

to[A]如果我想在要转换的对象内实现方法怎么办?让我们称之为DataFrame,我希望这段代码能够工作:

val df: DataFrame = ... …
Run Code Online (Sandbox Code Playgroud)

scala implicit shapeless

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