scala – 记录为参数,组成
编辑:我将问题重新表述为更简单,更少域名的问题:
在下面的代码中,我想实现mplus函数,该函数结合了由特定字段的存在约束的两个函数.结果函数应该受到两个字段的存在的约束. 谢谢 ! import shapeless._,ops.record.Selector,record._,syntax.singleton._ def requiresIntervalKey[L <: HList](l: L) (implicit sel: Selector.Aux[L,Witness.`"interval"`.T,Int]): Unit = { println(sel(l)) } def requiresPlatformField[L <: HList](l: L) (implicit sel: Selector.Aux[L,Witness.`"platform"`.T,String]): Unit = { println(sel(l)) } def mplus = ??? // That is the function I'd like to implement. Eventually it will be the additive operator of a monoid // needsBothFields: L <: HList -> (implicit) Selector.Aux[L,Int] -> (implicit) Selector.Aux[L,String] -> Unit val needsBothField = mplus(requiresIntervalKey _,requiresIntervalKey _ ) // Usage requiresIntervalKey(("interval" ->> "a string") :: HNil) // Shoudn't compile,value type is wrong requiresIntervalKey(("wrongKey" ->> "a string") :: HNil) // Shoudn't compile,"interval" key not provided requiresIntervalKey(("interval" ->> 42) :: HNil) // Compiles requiresPlatformField(("platform" ->> "EU") :: HNil) // Compiles needsBothFields(("interval" ->> 42) :: ("platform" ->> "EU") :: HNil) // Should compile //上一个问题版本 对于无形和类型级编程来说,我很难实现我的目标并获得清晰的理解.非常感谢您的帮助! 我基本上有几个函数如下所示: trait PathGenerator[T] { def apply(T): Set[Seq[String]] } val hourlyIntervalPathGenerator: PathGenerator[Interval] = ??? val constantGenerator: PathGenerator[String] = ??? // A Monoid[PathGenerator] // an implicit class adding a '/' operator to PathGenerator // Usage val hourlyRegionPathGenerator = hourlyIntervalPathGenerator / constantGenerator val paths = hourlyRegionPathGenerator(StaticIntervals.lastDay,"EU") 现在,当将两个以上的生成器一起添加时,用户必须使用嵌套元组.此外,命名生成器参数对于生成解析器非常有用(例如:cmd-line.) 无形记录似乎很合适,所以我继续实施以下非工作解决方案: 这个不可构建的代码和我无形的误解产生了几个问题: >从记录中获取字段的值(L26:键(“间隔”)和L35:键(常量))不会返回预期类型的??值,即使提供了Witness和选择器也很困难. 那么,记录是否是实现此用例的正确工具?代码段中未显示从PathPattern的记录形状/模板生成的命令行解析器. 我怎么能强制提供给生成器的记录(简单的或由几个组合产生的)在名称和类型方面具有完全正确的字段? 谢谢你的帮助! 编辑:这一系列问题和Travis Brown的答案非常相关: Passing a Shapeless Extensible Record to a Function 解决方法
这对Shapeless来说很有可能,尽管不是你想要的形式.这是一个简单的例子:
import shapeless._,syntax.singleton._ class UseKey[K <: String,V,R](w: Witness.Aux[K])(f: V => R) extends Poly1 { implicit def onRecord[L <: HList](implicit sel: Selector.Aux[L,K,V] ): Case.Aux[L,R] = at[L](l => f(sel(l))) } class Combine[P1 <: Poly1,P2 <: Poly1,R1,R2,R]( p1: P1,p2: P2 )(f: (R1,R2) => R) extends Poly1 { implicit def onRecord[L <: HList](implicit c1: p1.Case.Aux[L,R1],c2: p2.Case.Aux[L,R2] ): Case.Aux[L,Unit] = at[L](l => f(c1(l),c2(l))) } class mplus[P1 <: Poly1,P2 <: Poly1](p1: P1,p2: P2) extends Combine(p1,p2)((_: Unit,_: Unit) => ()) 然后: object requiresIntervalKey extends UseKey(Witness("interval"))( (i: Int) => println(i) ) object requiresPlatformField extends UseKey(Witness("platform"))( (s: String) => println(s) ) object needsBothFields extends mplus(requiresIntervalKey,requiresPlatformField) (作为旁注,我猜想你可以在这里写下UseKey(“平台”),但由于某种原因,捕获见证的隐式转换不起作用.幸运的是,Witness(“平台”)也不行坏.) 接下来显示它的工作原理: scala> import test.illTyped import test.illTyped scala> illTyped("""requiresIntervalKey("interval" ->> "a string" :: HNil)""") scala> illTyped("""requiresIntervalKey("wrongKey" ->> "a string" :: HNil)""") scala> requiresIntervalKey("interval" ->> 42 :: HNil) 42 scala> requiresPlatformField("platform" ->> "EU" :: HNil) EU scala> needsBothFields("interval" ->> 42 :: "platform" ->> "EU" :: HNil) 42 EU 我们需要Poly1而不是常规旧函数的原因是我们无法在组合普通函数时收集我们需要的不同证据 – 而是我们需要多态函数值(Shapeless提供为PolyN). 值得注意的是,这并非真正的“幺半群”.类型的monoid实例提供了一个操作,该操作接受该类型的两个值并返回另一个值.这里的mplus有两个操作,每个操作都有自己的隐含要求,并给我们另一个操作,它具有两者的组合要求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- bootstrap datetimepicker日期插件超详细使用方法
- BPM 是与非 -- 什么是BPM,如何辨别是否BPM产品,
- twitter-bootstrap – 摆脱Twitter Bootstrap缩略
- angularjs-$location
- BootStrap智能表单实战系列(三)分块表单配置详解
- angular – Reactive Forms正确地将Form Value转
- scala – 在Apache-spark中,如何添加稀疏向量?
- scala – 使用if-else中的重复代码减少代码重复
- Angular 4 – 当div进入视口时如何触发动画?
- 如何在bash中使用多个参数并将它们传递给awk?