2017-02-23 68 views
2

Дано:Генерирующие вложенные структуры данных в HList подобный стиль

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 имеет параметр типа или нет, но все детали работают. Я был бы рад любому другому решению с другими подходами, хотя, я думаю, мне понадобится некоторая зависящая от пути типизация во всех решениях. Может быть, некоторые неявные параметры могут направлять мой путь?

+0

Правильно ли я заметить, что список содержит элементы только типа 'String', и вы просто прикрепить«тип тега»(' float'), который вы хотите использовать спараметрировать ваш вложенная 'Array'? Таким образом, у вас действительно нет «HList», но вы используете «HList» только для подсчета уровня вложенности? – ziggystar

+0

Исправить. Чем больше элементов в списке, тем больше гнездования я хочу иметь. Это не бесформенный «HList», я просто подумал, что может быть какая-то магия, основанная на HList, которую я мог бы наложить. Для немного другого контекста: я хочу создать слой с тифами вокруг javaish API, который требует отбрасывания массивов, которые могут иметь многомерные массивы, имена - это имена осей координат, используемых для описания данных. –

+0

Благодарим за более краткий обзор http://stackoverflow.com/questions/42410653/is-there-infrastructure-in-shapeless-that-takes-a-type-constructor-to-power о бесформенном :) –

ответ

1

Правильно ли я вижу, что список содержит элементы только типа String, и вы просто присоединяете «тег типа» (Float), который вы хотите использовать для параметризации вашего вложенного массива? Таким образом, у вас действительно нет HList, но вы используете «HList» просто для подсчета уровня гнездования?

Следующий код может использоваться для построения вложенных массивов путем вызова функции step. Добавление имен должно быть тривиальным.

scalafiddle.io

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)) 
+0

Got это работать с использованием вашего подхода, большое спасибо –