Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Last active January 18, 2019 08:12
Show Gist options
  • Save yasuabe/a64e9f9afae85d1f07ef4f55e4689eec to your computer and use it in GitHub Desktop.
Save yasuabe/a64e9f9afae85d1f07ef4f55e4689eec to your computer and use it in GitHub Desktop.
implement vector and matrix with Shapeless's Sized
import shapeless.Nat._
import shapeless.ops.nat.ToInt
import shapeless.syntax.sized._
import shapeless.{Nat, Sized}
type Vect[N <: Nat] = Sized[IndexedSeq[Int], N]
def vect = Sized.apply[IndexedSeq]
def times[L <: Nat](k: Int, v1: Vect[L]): Vect[L] = v1.map(_ * k)
times(3, vect(1, 2)) // (3, 6)
times(0, vect(1, 2)) // (0, 0)
def addVect[L <: Nat](v1: Vect[L], v2: Vect[L]): Vect[L] =
Sized.wrap[IndexedSeq[Int], L]((v1, v2).zipped.map(_ + _))
addVect(Sized(1, 2, 3), Sized(3, 4, 5)) // (4, 6, 8)
List(vect(10), vect(100)).fold[Vect[_1]](vect(1))(addVect) // (111)
// addVect(vect(1, 2, 3), vect(3, 4)) type mismatch
Sized.wrap[IndexedSeq[Int], Nat._3](IndexedSeq(1, 23))
IndexedSeq(1, 23).sized[Nat._3]
type Matrix[R <: Nat, C <: Nat] = Sized[IndexedSeq[Vect[C]], R]
def matrix = Sized.apply[IndexedSeq]
def multiply[R <: Nat, RC <: Nat, C <: Nat](
m1: Matrix[R, RC],
m2: Matrix[RC, C]
)(implicit R: ToInt[R], C: ToInt[C]): Matrix[R, C] = m1.map(w1 =>
Sized.wrap[IndexedSeq[Int], C](
m2.transpose.map(w2 => (w1, w2).zipped.map(_ * _).sum))
)
val m1: Matrix[_3, _2] = //[[1, 2]
matrix(vect(1, 2), vect(3, 4), vect(5, 6)) // [3, 4]
// [5, 6]]
val m2: Matrix[_2, _4] = //[[ 7, 8, 9, 10]
matrix(vect(7, 8, 9, 10), vect(11, 12, 13, 14)) // [11, 12, 13, 14]]
// val m3: Matrix[_3, _2] = matrix(vect(1, 2), vect(3, 4, 5), vect(5, 6))
multiply(m1, m2) // [[ 29, 32, 35, 38]
// [ 65, 72, 79, 86]
// [101, 112, 123, 134]]
// multiplyVect(m1, m2) type mismatch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment