Skip to content

Instantly share code, notes, and snippets.

@logicalguess
Last active September 11, 2017 04:21
Show Gist options
  • Select an option

  • Save logicalguess/32c4b9bd1693dd2c03a5c12f61e9fa68 to your computer and use it in GitHub Desktop.

Select an option

Save logicalguess/32c4b9bd1693dd2c03a5c12f61e9fa68 to your computer and use it in GitHub Desktop.
e.g. combining an HList of functions into a partial function
package logicalguess
import shapeless.{::, HList, HNil}
trait HListFolder[In <: HList, Out] {
def apply(in: In): Out
}
object HListFolder {
implicit def apply[L <: HList, Out](in: L)(implicit folder: HListFolder[L, Out]) = folder(in)
implicit def caseHNil[Out](implicit zero: Out): HListFolder[HNil, Out] = new HListFolder[HNil, Out] {
def apply(in: HNil) = zero
}
implicit def caseHList[H, T <: HList, Out]
(
implicit
headFolder: (H, Out) => Out,
tailFolder: HListFolder[T, Out]
): HListFolder[H :: T, Out] = new HListFolder[H :: T, Out] {
def apply(in: H :: T) = headFolder(in.head, tailFolder(in.tail))
}
}
object Test {
type Out = PartialFunction[Any, Any]
implicit val zero: Out = {
case a => a
}
//inefficient, for demo purposes only
implicit def fold[I, O]: (Function[I, O], Out) => Out =
(f, pf) => {
PartialFunction[Any, Any] {
case a => {
try {
f(a.asInstanceOf[I])
} catch {
case e: Exception => pf(a)
}
}
}
}
def main(args: Array[String]): Unit = {
case class Input(value: String)
case class Output(value: String)
import HListFolder._
val functions = ((s: String) => s.length) :: ((c: Input) => Output(c.value)) :: HNil
val res4 = functions(Input("functions hi"))
println(res4 + ": " + res4.getClass)
//Output(functions hi): class logicalguess.Test$Output$3
val res5 = functions("functions abc")
println(res5 + ": " + res5.getClass)
//13: class java.lang.Integer
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment