以类似 HList 的样式生成嵌套数据结构
Generating nested data structures in a HList-like style
鉴于:
val a = "foo" :: "bar" :: MyNil[Float]()
我希望 a.ArrayType
解析为 Array[Array[Float]]
,以及 a.toList
生成 Seq("foo", "bar")
。对于更长的列表,a.ArrayType
应该嵌套得更深,但叶类型应该保持不变。
我正在尝试定义一个允许上述操作的数据结构,但到目前为止我自己的尝试失败了。
我有一些方法并不完全有效。要么我没有完成感应步骤,要么感应开始。也许有一些我没有看到的支持无形的解决方案?这是我到目前为止未能开始感应的地方:
trait NestedArrays[A] {
type BaseType = A
type ArrayType <: Array[_]
val name: String
val t: NestedArrays[A]
def ::(name: String): ::[A] = new ::(name, this)
def toList: List[String] = name :: t.toList
}
case class ::[A](name: String, t: NestedArrays[A]) extends NestedArrays[A] {
override type BaseType = t.BaseType
override type ArrayType = Array[t.ArrayType]
}
class HANil[A] extends NestedArrays[A] {
override type BaseType = A
override type ArrayType = A
override val t: NestedArrays[A] = null
override val name: String = null
override def toList: List[String] = Nil
}
object HANil {
def apply[A](): NestedArrays[A] = new HANil[A]
// val test = "bar" :: "baz" :: "foo" :: begin[Float]("bal")
val test = "foo" :: "bar" :: HANil[Float]()
//val test = begin[Float]("boo")
val a = Array.ofDim[Float](2, 2).asInstanceOf[test.ArrayType]
}
我的其他解决方案围绕 ArrayType
是否必须是数组(如果不是,归纳步骤失败,但开始有效)或 NestedArrays
是否具有类型参数而有所不同,但这都是细节工作。我也会对使用其他方法的任何其他解决方案感到高兴,尽管我想我需要在所有解决方案中进行一些依赖于路径的输入。也许一些隐式参数可以指导我的方式?
我是否正确地观察到列表仅包含字符串类型的元素,而您只需附加一个要用于参数化嵌套数组的 "type tag" (Float
)?所以你并没有真正的 HList
,但你使用“HList
”只是为了计算嵌套级别?
以下代码可用于通过调用 step
函数来构建嵌套数组。添加名称应该是微不足道的。
trait I {
type Out
def step: I.Aux[Array[Out]] = I[Array[Out]]
def create(x: Any): Out = x.asInstanceOf[Out]
}
object I {
type Aux[X] = I {type Out = X}
def apply[A]: Aux[A] = new I {type Out = A}
}
val x: Float = I[Float].create(1)
val ax: Array[Float] = I[Float].step.create(Array(0.1f))
val aax: Array[Array[Float]] = I[Float].step.step.create(Array(Array(0.1f)))
//The following fail to compile
//val aax2: Array[Array[Float]] = I[Float].step.create(Array(0.1f))
//val aax3: Array[Float] = I[Float].step.step.create(Array(0.1f))
鉴于:
val a = "foo" :: "bar" :: MyNil[Float]()
我希望 a.ArrayType
解析为 Array[Array[Float]]
,以及 a.toList
生成 Seq("foo", "bar")
。对于更长的列表,a.ArrayType
应该嵌套得更深,但叶类型应该保持不变。
我正在尝试定义一个允许上述操作的数据结构,但到目前为止我自己的尝试失败了。
我有一些方法并不完全有效。要么我没有完成感应步骤,要么感应开始。也许有一些我没有看到的支持无形的解决方案?这是我到目前为止未能开始感应的地方:
trait NestedArrays[A] {
type BaseType = A
type ArrayType <: Array[_]
val name: String
val t: NestedArrays[A]
def ::(name: String): ::[A] = new ::(name, this)
def toList: List[String] = name :: t.toList
}
case class ::[A](name: String, t: NestedArrays[A]) extends NestedArrays[A] {
override type BaseType = t.BaseType
override type ArrayType = Array[t.ArrayType]
}
class HANil[A] extends NestedArrays[A] {
override type BaseType = A
override type ArrayType = A
override val t: NestedArrays[A] = null
override val name: String = null
override def toList: List[String] = Nil
}
object HANil {
def apply[A](): NestedArrays[A] = new HANil[A]
// val test = "bar" :: "baz" :: "foo" :: begin[Float]("bal")
val test = "foo" :: "bar" :: HANil[Float]()
//val test = begin[Float]("boo")
val a = Array.ofDim[Float](2, 2).asInstanceOf[test.ArrayType]
}
我的其他解决方案围绕 ArrayType
是否必须是数组(如果不是,归纳步骤失败,但开始有效)或 NestedArrays
是否具有类型参数而有所不同,但这都是细节工作。我也会对使用其他方法的任何其他解决方案感到高兴,尽管我想我需要在所有解决方案中进行一些依赖于路径的输入。也许一些隐式参数可以指导我的方式?
我是否正确地观察到列表仅包含字符串类型的元素,而您只需附加一个要用于参数化嵌套数组的 "type tag" (Float
)?所以你并没有真正的 HList
,但你使用“HList
”只是为了计算嵌套级别?
以下代码可用于通过调用 step
函数来构建嵌套数组。添加名称应该是微不足道的。
trait I {
type Out
def step: I.Aux[Array[Out]] = I[Array[Out]]
def create(x: Any): Out = x.asInstanceOf[Out]
}
object I {
type Aux[X] = I {type Out = X}
def apply[A]: Aux[A] = new I {type Out = A}
}
val x: Float = I[Float].create(1)
val ax: Array[Float] = I[Float].step.create(Array(0.1f))
val aax: Array[Array[Float]] = I[Float].step.step.create(Array(Array(0.1f)))
//The following fail to compile
//val aax2: Array[Array[Float]] = I[Float].step.create(Array(0.1f))
//val aax3: Array[Float] = I[Float].step.step.create(Array(0.1f))