Skip to content

Instantly share code, notes, and snippets.

@ceedubs
Created February 25, 2015 23:25
Show Gist options
  • Save ceedubs/2b4e26796797594c08bc to your computer and use it in GitHub Desktop.
Save ceedubs/2b4e26796797594c08bc to your computer and use it in GitHub Desktop.
HStack and HDequeue
import scalaz._
import shapeless._
import shapeless.ops.hlist._
/** contrived IndexedState example */
object HStack extends App {
def push[H, T <: HList](h: H): IndexedState[T, H :: T, H] =
IndexedState(t => (h :: t, h))
def pop[H, T <: HList]: IndexedState[H :: T, T, H] =
IndexedState(l => (l.tail, l.head))
def peek[H, T <: HList]: IndexedState[H :: T, H :: T, H] =
IndexedState(l => (l, l.head))
def app[L <: HList] = for {
_ <- push[Int, L](1)
_ <- push("foo")
foo <- pop
_ <- push(foo + "bar")
foobar <- peek
} yield foobar
println(app("baz" :: true :: 64L :: HNil))
}
final case class HDequeue[L <: HList, R <: HList](l: L, r: R)
object HDequeue extends App {
def pushFront[A, L <: HList, R <: HList](a: A): IndexedState[HDequeue[L, R], HDequeue[A :: L, R], A] =
IndexedState(s1 => (HDequeue(a :: s1.l, s1.r), a))
def pushBack[A, L <: HList, R <: HList](a: A): IndexedState[HDequeue[L, R], HDequeue[L, A :: R], A] =
IndexedState(s1 => (HDequeue(s1.l, a :: s1.r), a))
def popFront[L <: HList, R <: HList](implicit p: PopFront[L, R]): IndexedState[HDequeue[L, R], p.DOut, p.A] =
IndexedState(p(_))
def app[L <: HList, R <: HList] = for {
_ <- pushFront[Int, L, R](1)
foo <- pushBack("foo")
one <- popFront[Int :: L, String :: R]
} yield one
println(app(HDequeue("baz" :: true :: HNil, 64L :: HNil)))
println(popFront[HNil, Long :: HNil].apply(HDequeue(HNil, 64L :: HNil)))
}
sealed trait PopFront[L <: HList, R <: HList] {
type A
type LOut <: HList
type ROut <: HList
type DOut = HDequeue[LOut, ROut]
def apply(d: HDequeue[L, R]): (HDequeue[LOut, ROut], A)
}
sealed trait PopFrontInstances0 {
type Aux[L <: HList, R <: HList, _A, _LOut <: HList, _ROut <: HList] = PopFront[L, R] {
type A = _A
type LOut = _LOut
type ROut = _ROut
}
implicit def popFrontLeft[_A, LT <: HList, R <: HList]: Aux[_A :: LT, R, _A, LT, R] =
new PopFront[_A :: LT, R] {
type A = _A
type LOut = LT
type ROut = R
def apply(d: HDequeue[A :: LT, R]) = (HDequeue(d.l.tail, d.r), d.l.head)
}
}
object PopFront extends PopFrontInstances0 {
implicit def popFrontRight[_A, RT <: HList]: Aux[HNil, _A :: RT, _A, HNil, RT] =
new PopFront[HNil, _A :: RT] {
type A = _A
type LOut = HNil
type ROut = RT
def apply(d: HDequeue[HNil, _A :: RT]) = (HDequeue(HNil, d.r.tail), d.r.head)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment