Achieving compile safe indexing with Shapeless

痞子三分冷 提交于 2020-01-05 04:26:07

问题


Problem: Let val v = List(0.5, 1.2, 0.3) model a realisation of some vector v = (v_1, v_2, v_3). The index j in v_j is implied by the element's position in the list. A lot of boilerplate and bugs have been due to tracking these indices, eg, when creating modified lists from the original. (How to make sure (in compile-time) that collection wasn't reordered? seems related.)

General question: What could be a good way to ensure correct indexing at compile time? (I assume that performance is not essential.)

My plan is to use subclasses of Nat in shapeless to model the indices as (explicit) types. The current solution is

import shapeless._
import Nat._

trait Elem[+A, +N<:Nat]{
    val v: A
    val ind: N}

case class DecElem[N<:Nat](v: BigDecimal, ind: N) extends Elem[BigDecimal, N]

object Decimals {
type One = DecElem[ _0]:: HNil
type Two =  DecElem[ _0]:: DecElem[_1] :: HNil
//...
}
case class Scalar(v: Decimals.One)
case class VecTwo(v: Decimals.Two)

This, however, gets tedious in larger dimensions. Another question is how to approach the generic case in trait Elem[+A, +N<:Nat]. As a start, I defined case class ElemVector[A, M<:Nat](vs: Sized[List[Elem[A, Nat]], M]), which loses the specific index type in Elem. What might be a strategy to circumvent this difficulty?

(Note: A better design may be to wrap List[A] by attaching explicit indices and deal with wrapper class. This, however, does not essentially change the question.)

UPDATE Here's is a trivial illustration of accidental swapping of vector elements.

import shapeless.Nat._
import shapeless.{Sized, nat}

type VectorTwo = Sized[IndexedSeq[Double], nat._2]

val f = (p: VectorTwo, x: Double) => {
  val V = p(_0)
  val K = p(_1)

  V * x/(K + x)
}

val V : Double = 500
val K : Double = 1

val correct: VectorTwo = Sized(V, K)
val wrong: VectorTwo = Sized(K, V)  //Compiles!


f(correct, 10)  // = 454.54
f(wrong, 10)    // =   0.02

I'd like to enlist the compiler to prevent such errors in vectors with many elements, and wonder if there could be an elegant solution with Shapeless.

来源:https://stackoverflow.com/questions/48328854/achieving-compile-safe-indexing-with-shapeless

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!