Shapeless 中具有常量返回类型的多态函数

2024-04-17

长话短说,我试图弄清楚如何定义从通用输入到单一类型输出的函数。

的背景:这是一个延续映射无形状记录 https://stackoverflow.com/questions/26375886/mapping-over-shapeless-record. After 特拉维斯的出色回答 https://stackoverflow.com/a/26384377/807674,我现在有以下内容:

import shapeless._
import poly._
import syntax.singleton._
import record._

type QueryParams = Map[String, Seq[String]]

trait RequestParam[T] {
  def value: T

  /** Convert value back to a query parameter representation */
  def toQueryParams: Seq[(String, String)]

  /** Mark this parameter for auto-propagation in new URLs */
  def propagate: Boolean

  protected def queryStringPresent(qs: String, allParams: QueryParams): Boolean = allParams.get(qs).nonEmpty
}

type RequestParamBuilder[T] = QueryParams => RequestParam[T]

def booleanRequestParam(paramName: String, willPropagate: Boolean): RequestParamBuilder[Boolean] = { params =>
  new RequestParam[Boolean] {
    def propagate: Boolean = willPropagate
    def value: Boolean = queryStringPresent(paramName, params)
    def toQueryParams: Seq[(String, String)] = Seq(paramName -> "true").filter(_ => value)
  }
}

def stringRequestParam(paramName: String, willPropagate: Boolean): RequestParamBuilder[Option[String]] = { params =>
  new RequestParam[Option[String]] {
    def propagate: Boolean = willPropagate
    def value: Option[String] = params.get(paramName).flatMap(_.headOption)
    def toQueryParams: Seq[(String, String)] = value.map(paramName -> _).toSeq
  }
}

实际上,下面是一个类构造函数,它将从查询字符串中读取的 Map 作为参数,但为了简单起见,我只是定义一个val:

val requestParams = Map("no_ads" -> Seq("true"), "edition" -> Seq("us"))

// In reality, there are many more possible parameters, but this is simplified
val options = ('adsDebug ->> booleanRequestParam("ads_debug", true)) ::
  ('hideAds ->> booleanRequestParam("no_ads", true)) ::
  ('edition ->> stringRequestParam("edition", false)) ::
  HNil

object bind extends FieldPoly {
  implicit def rpb[T, K](implicit witness: Witness.Aux[K]): Case.Aux[
      FieldType[K, RequestParamBuilder[T]],
      FieldType[K, RequestParam[T]]
    ] = atField(witness)(_(requestParams))
}

// Create queryable option values record by binding the request parameters
val boundOptions = options.map(bind)

这让我可以这样做:

boundOptions.get('hideAds).value // -> true

问题:现在我希望能够重新序列化具有propagate = true。所以基本上,我需要过滤我的HList on the propagate每个成员的字段,应该始终返回一个Boolean,然后让每个参数将自身重新序列化为Seq[(String, String)]。我尝试过以下方法:

object propagateFilter extends (RequestParam ~> Const[Boolean]) {
  override def apply[T](r: RequestParam[T]): Boolean = r.propagate
}   

object unbind extends (RequestParam ~> Const[Seq[(String, String)]]) {
  override def apply[T](r: RequestParam[T]): Seq[(String, String)] = r.toQueryParams
}

// Reserialize a query string for options that should be propagated
val propagatedParams = boundOptions.values.filter(propagateFilter).map(unbind).toList 
// (followed by conventional collections methods)

,但它不喜欢我的功能。我收到以下错误:

<console>:31: error: type mismatch;
 found   : Boolean
 required: shapeless.Const[T]
    (which expands to)  AnyRef{type λ[T] = T}
             override def apply[T](r: RequestParam[T]) = r.propagate

我相信我对一个应该具有多态输入但单态输出的函数采取了错误的方法。

其他失败的尝试:

object propagateFilter extends Poly1 {
  implicit def default[T](implicit st: Case.Aux[RequestParam[T], Boolean]) = at[RequestParam[T]](_.propagate)
}

and

def propagate[T](x: RequestParam[T]): Boolean = x.propagate

and

object propagateFilter extends Poly1 {
  implicit def default = at[RequestParam[_]](_.propagate)
}

and

object propagateFilter extends FieldPoly {
  implicit def rpb[T, K](implicit witness: Witness.Aux[K]): Case.Aux[
    FieldType[K, RequestParam[T]],
    Boolean
    ] = atField(witness)(_.propagate)
}

这些都不起作用,可能是由于我自己对正在发生的事情的误解。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shapeless 中具有常量返回类型的多态函数 的相关文章

  • 清理 IntelliJ 中构建的 Play 框架

    我有一个拼写错误conf routes文件导致 Play Framework 生成错误命名的类 重建项目并运行Invalidate Caches并没有解决 IntelliJ 中的问题 当我手动运行时重新生成了不正确的类文件play clea
  • 如何将模型从 ML Pipeline 保存到 S3 或 HDFS?

    我正在尝试保存 ML Pipeline 生成的数千个模型 正如答案中所示here https stackoverflow com questions 32121046 run 3000 random forest models by gro
  • 如何从字符串列中提取数字?

    我的要求是从列中的评论列中检索订单号comment并且总是开始于R 订单号应作为新列添加到表中 输入数据 code id mode location status comment AS SD 101 Airways hyderabad D
  • 如何以最佳方式传递元组参数?

    如何以最佳方式传递元组参数 Example def foo Int Int def bar a Int b Int 现在我想传递的输出foo to bar 这可以通过以下方式实现 val fooResult foo bar fooResul
  • Spark日期格式问题

    我在火花日期格式中观察到奇怪的行为 实际上我需要转换日期yy to yyyy 日期转换后 日期应为 20yy 我尝试过如下 2040年后失败 import org apache spark sql functions val df Seq
  • 在 Akka 中配置嵌套 Router

    我有一些嵌套的路由器 应创建它FromConfig 我想要的是这样的 test akka actor deployment worker router round robin nr of instances 5 slave router b
  • 如何在 Apache Spark 中通过 DStream 使用特征提取

    我有通过 DStream 从 Kafka 到达的数据 我想进行特征提取以获得一些关键词 我不想等待所有数据的到达 因为它是可能永远不会结束的连续流 所以我希望以块的形式执行提取 如果准确性会受到一点影响 对我来说并不重要 到目前为止 我整理
  • 更改 build.sbt 自定义任务中的版本

    我在 build sbt 中定义了一个自定义任务 val doSmth taskKey Unit smth doSmth version 1 0 SNAPSHOT 但它不会改变版本 我真正想要的是自定义 sbt 发布任务 它将始终将相同的版
  • 高效序列化案例类

    对于我正在工作的图书馆 我需要提供一个高效 便捷 typesafe序列化 scala 类的方法 理想的情况是用户可以创建一个案例类 并且只要所有成员都是可序列化的 它似乎也应该如此 我准确地知道序列化和反序列化阶段的类型 因此不需要 也不能
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • 如何使用 Spark 2 屏蔽列?

    我有一些表 我需要屏蔽其中的一些列 要屏蔽的列因表而异 我正在读取这些列application conf file 例如 对于员工表如下所示 id name age address 1 abcd 21 India 2 qazx 42 Ger
  • 为什么用scala写的代码比用java写的慢6倍?

    我不确定我在编写 scala 代码时是否犯了一些错误 问题是 The four adjacent digits in the 1000 digit number that have the greatest product are 9 9
  • 如何在超时的情况下在单独的调度程序上运行 Akka Streams 图?

    这个问题是基于我做过的一个宠物项目 这个SO https stackoverflow com questions 34641861 akka http blocking in a future blocks the server 34645
  • 在scala 2.13中,为什么有时无法显式调用类型类?

    这是 Shapeless 2 3 3 中的一个简单示例 val book author gt gt Benjamin Pierce title gt gt Types and Programming Languages id gt gt 2
  • 为什么自类型类可以声明类

    我知道 Scala 只能混合特征 这对于依赖注入和蛋糕模式是有意义的 我的问题是为什么我仍然可以声明一个需要另一个 类 但不需要特征的类 Code class C class D self C gt 这仍然编译成功 我认为它应该编译失败 因
  • 如何在 sbt 控制台中加载 scala 文件? [复制]

    这个问题在这里已经有答案了 可能的重复 将 Scala 文件加载到解释器中以使用函数 https stackoverflow com questions 7383436 load scala file into interpreter to
  • 获取SettingKey[T]的值

    我正在开发一个用于文档生成的插件 我想将所有生成的文件输出到我选择的目录中 该目录可以是SBT的子目录target目录 如下 val newTargetDirectory SettingKey File document target di
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • 使用 Shapeless 记录组合任意数量的状态更改函数

    我正在尝试移植combineReducers从 Redux 到 Scala 这个想法是每个函数控制它的一小部分状态并且combineReducers创建一个控制整个状态的函数 我无法找出应该像这样工作的函数所需的签名 sealed trai
  • 如何关闭 Scala 中因方法重载而导致代码无法编译的特定隐式?

    我正忙着尝试自己回答这个问题 Scala Play 2 4 x 通过 anorm MySQL 处理扩展字符到 Java Mail https stackoverflow com questions 31417718 scala play 2

随机推荐