带有额外约束的 Scala 无形 KList [英] Scala shapeless KList with extra constraint

查看:42
本文介绍了带有额外约束的 Scala 无形 KList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想采用这种模式:

 def accept[T](a: RList[T]) = true
 def accept[T, V](a: RList[T], b: RList[V])(implicit ev: a.S =:= b.S) = true
 def accept[T, V, Q](a: RList[T], b: RList[V], c: RList[Q])(implicit ev: a.S =:= b.S, ev2: b.S =:= c.S) = true

但让它接受一个 KList,而不是手动覆盖所有参数.基本上我想说,采用任意数量的 RList,它们具有相同的 S 成员类型"

but have it accept a KList, instead of manually overriding for all arities. Basically I want to say, "Take any number of RLists, that have the same S member type"

RList 是一个 trait,它包含一个类型 S.(有关 RList 的更多背景以及我这样做的原因,请参阅:基于原点的约束函数(路径依赖类型?类型生成?))

RList is a trait, that contains a type S. (For more background on an RList and why I'm doing this, see: Constrain function based on origin (Path Dependent type? Type Generation?))

推荐答案

看起来您所做的只是试图让编译器检查类型是否一致,因为您的方法总是返回 true.

It looks like what you are doing is just trying to get the compiler to check that the types agree, since your methods ALWAYS return true.

您是否可以接受一个RLists 列表",而不是接受任意数量的这些方法,而是保证所有 S 匹配?

Can you perhaps, instead of making methods which accept an arbitrary number of these, accept a "List of RLists" which is guaranteed to have S all matching?

以下是构建这样一个列表的方法:

Here is how such a list might be constructed:

package rl {

// A simplified version of your RList:
trait RList[T] {
  type S
  def data: List[T]
}

// A list of RLists which have identical S
sealed trait RListList 

// RListNil is an empty list
trait RListNil extends RListList {
  def ::[H <: RList[_]](h: H) = rl.::[h.S,H,RListNil](h, this)
}
// there is exactly one RListNil
case object RListNil extends RListNil

// List can be a cons cell of lists sharing the same S
final case class ::[S, H <: RList[_], T <: RListList](head: H, tail: T) extends RListList {

  // We only allow you to cons another to this if we can find evidence that the S matches
  def ::[H2 <: RList[_]](h: H2)(implicit ev: =:=[h.S,S]) = rl.::[S,H2,::[S,H,T]](h, this)
}

现在,如果我们尝试构造一个 RListList 没有所有 S 类型都一致,编译器会抓住我们:

Now, if we try to construct a RListList that doesn't have all the S types agreeing, the compiler will catch us:

object RListTest {

  val list1 = new RList[Int] { type S = String; def data = List(1,2,3,4) }
  val list2 = new RList[String] { type S = String; def data = List("1","2","3","4") }
  val list3 = new RList[Double] { type S = Float; def data = List(1.1,2.2,3.3,4.4) }

  val listOfLists1 = list1 :: RListNil // fine
  val listOfLists2 = list2 :: listOfLists1 // still fine, since list1 and list2 have the same S
  val listOfLists3 = list3 :: listOfLists2 // compiler error: Cannot prove that java.lang.String =:= Float

}

这是使用依赖方法类型,这意味着您需要使用 scala 2.10 或者您需要使用 2.9.x 中的 -Ydependent-method-types 开关进行编译

This is using dependent method types, which means you need to use scala 2.10 or you need to compile with the -Ydependent-method-types switch in 2.9.x

这篇关于带有额外约束的 Scala 无形 KList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆