Skip to content

Instantly share code, notes, and snippets.

@nbenns
Last active June 10, 2018 17:09
Show Gist options
  • Save nbenns/ede83f86c2595ee0693dbb8d5038464e to your computer and use it in GitHub Desktop.
Save nbenns/ede83f86c2595ee0693dbb8d5038464e to your computer and use it in GitHub Desktop.
Play with adding size of col and row as type parameters to a matrix
import shapeless.ops.hlist.Length
import shapeless.{::, HList, HNil, LUBConstraint, Nat, Poly1, Succ}
import shapeless.Nat._
abstract class Matrix[Col <: Nat, Row <: Nat, A] {
type RowLst <: HList
type ConLst <: HList
val data: ConLst
}
object Matrix {
type Aux[C <: Nat, R <: Nat, A, H <: HList, T <: HList] = Matrix[C, R, A] {
type RowLst = H
type ConLst = H :: T
}
def apply
[HH, HT <: HList, T <: HList, C <: Nat, R <: Nat]
(d: (HH :: HT) :: T)
(implicit
lcRow: LUBConstraint[HT, HH], // Everything in the "tail of the head" must match the "head of the head"
lcCol: LUBConstraint[T, HH :: HT], // Everything in the tail must match the head (HH :: HT)
lcol: Length.Aux[HH :: HT, C], // The length of the columns is the length of the first row aka Head (HH :: HT)
lrow: Length.Aux[(HH::HT)::T, R] // The length of the rows is the length of the whole list (Head :: T) or ((HH :: HT) :: T)
): Matrix[C, R, HH]
= new Matrix[C, R, HH] {
type RowLst = HH :: HT
type ConLst = (HH :: HT) :: T
val data: ConLst = d
}
}
object Main extends App {
val row1 = HList(1, 2, 3)
val row2 = HList(4, 5, 6)
val matrix: Matrix[_3, _2, Int] = Matrix(row1 :: row2 :: HNil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment