Skip to content

Instantly share code, notes, and snippets.

@andyscott
Last active November 6, 2017 00:41
Show Gist options
  • Save andyscott/f230e85d5d2fb7c1aa4ee914ce0d0cde to your computer and use it in GitHub Desktop.
Save andyscott/f230e85d5d2fb7c1aa4ee914ce0d0cde to your computer and use it in GitHub Desktop.
import iota._
import iota.TList.::
import iota.TList.Op
import iota.syntax.inject._
def foldTo[B]: CopFoldTo[B] = new CopFoldTo[B]
class CopFoldTo[B] {
// library code to add to iota
def apply[L <: TList, LF <: TList](a: Cop[L])(fs: Prod[LF])(
implicit ev: TList.Compute.Aux[Op.Map[? => B, L], LF]
): B =
fs.values(a.index).asInstanceOf[Any => B].apply(a.value)
}
case class Finn()
case class Cinder()
case class Bridger()
type Dog = Cop[Finn :: Cinder :: Bridger :: TNil]
val dogs: List[Dog] = List(
Bridger().inject[Dog],
Finn().inject[Dog],
Cinder().inject[Dog],
Bridger().inject[Dog],
Finn().inject[Dog])
val res: List[String] = dogs.map(dog =>
foldTo[String](dog)(Prod(
(f: Finn) => s"we got finn $f",
(c: Cinder) => s"we got cinder $c",
(b: Bridger) => s"we got bridger $b")))
println(res)
// List(
// we got bridger Bridger(),
// we got finn Finn(),
// we got cinder Cinder(),
// we got bridger Bridger(),
// we got finn Finn())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment