Skip to content

Instantly share code, notes, and snippets.

@ssimeonov
Last active January 20, 2016 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssimeonov/5cc202cf9c4844a94de2 to your computer and use it in GitHub Desktop.
Save ssimeonov/5cc202cf9c4844a94de2 to your computer and use it in GitHub Desktop.
object ContrivedAdd {
import shapeless._
import record._
import syntax.singleton._
import shapeless.ops.record.Updater
import scalaz._
import Scalaz._
case class S[L <: HList](total: Int, scratch: L)
// addField works w/o any type parameters in contrivedAdd() below
def addField[K <: Symbol, A, L <: HList](k: Witness, a: A)(f: Int => Int)
: IndexedState[S[L], S[FieldType[K, A] :: L], Unit] =
IndexedState(s => (S(f(s.total), field[K](a) :: s.scratch), ()))
// with updateField() the compiler is either confused about which implicit to use or cannot find an implicit
def updateField[K <: Symbol, A, L <: HList](k: Witness, a: A)(f: Int => Int)
(implicit updater: Updater[L, FieldType[k.T, A]])
: IndexedState[S[L], S[updater.Out], Unit] =
IndexedState(s => (S(f(s.total), updater(s.scratch, field[k.T](a))), ()))
def contrivedAdd[L <: HList](n: Int) = for {
a <- init[S[L]]
_ <- addField('latestAdded, n + 123)(_ + n)
_ <- updateField('latestAdded, n)(_ + n)
// ambiguous implicit values:
// both method hnilUpdater in object Updater of type [L <: shapeless.HNil, F]=> shapeless.ops.record.Updater.Aux[L,F,shapeless.::[F,shapeless.HNil]]
// and method hlistUpdater2 in object Updater of type [K, V, T <: shapeless.HList]=> shapeless.ops.record.Updater.Aux[shapeless.::[shapeless.record.FieldType[K,V],T],shapeless.record.FieldType[K,V],shapeless.::[shapeless.record.FieldType[K,V],T]]
// match expected type shapeless.ops.record.Updater[L,Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("latestAdded")],Int]]
// _ <- updateField('latestAdded, n)(_ + n)
// ^
// If, instead the type parameters are provided, the implicit cannot be found
// _ <- updateField[Symbol, Int, L]('latestAdded, n)(_ + n)
// could not find implicit value for parameter updater: shapeless.ops.record.Updater[L,Int with shapeless.record.KeyTag[Symbol with shapeless.tag.Tagged[String("latestAdded")],Int]]
// _ <- updateField[Symbol, Int, L]('latestAdded, n)(_ + n)
// ^
r <- get
} yield r.total
def main(args: Array[String] = Array()): Unit = {
val initialState = S(0, ('a ->> 5) :: HNil)
val result = contrivedAdd(555).run(initialState)
println(result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment