Last active
December 29, 2015 06:19
-
-
Save pomadchin/7628073 to your computer and use it in GitHub Desktop.
shapeless custom type filter for functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Type class supporting access to the all elements of this `HList` for functions from type `U` ~(`U => V`). | |
* | |
* author of original HList Filter Alois Cochard | |
* | |
* @author Grigory Pomadchin | |
*/ | |
object am3 { | |
trait FuncFilter[L <: HList, U] extends DepFn1[L] { type Out <: HList } | |
object FuncFilter { | |
def apply[L <: HList, U](implicit filter: FuncFilter[L, U]): Aux[L, U, filter.Out] = filter | |
type Aux[L <: HList, U, Out0 <: HList] = FuncFilter[L, U] { type Out = Out0 } | |
implicit def nil[L <: HList, U]: Aux[HNil, U, HNil] = | |
new FuncFilter[HNil, U] { | |
type Out = HNil | |
def apply(l : HNil): Out = HNil | |
} | |
implicit def pick[F, T, L <: HList, U] | |
(implicit f : FuncFilter[L, U], e : U =:= F): Aux[(F => T) :: L, U, (F => T) :: f.Out] = | |
new FuncFilter[(F => T) :: L, U] { | |
type Out = (F => T) :: f.Out | |
def apply(l : (F => T) :: L) : Out = l.head :: f(l.tail) | |
} | |
implicit def drop[F, T, L <: HList, U] | |
(implicit f : FuncFilter[L, U], e : U =:!= F): Aux[(F => T) :: L, U, f.Out] = | |
new FuncFilter[(F => T) :: L, U] { | |
type Out = f.Out | |
def apply(l : (F => T) :: L): Out = f(l.tail) | |
} | |
} | |
} | |
import am3._ | |
object mapFilter extends Poly1 { | |
implicit def default[F, T, L <: HList](implicit f: FuncFilter[L, F]) = | |
at[(F => T, L)] { case (_, l) => f(l) } | |
} | |
// usage example | |
// S => A, S => C, ... , etc | |
val cList = | |
S.sToA _ :: | |
S.sToC _ :: | |
A.aToB _ :: | |
B.bToD _ :: | |
D.dToC _ :: HNil | |
cList zip(cList mapConst cList) map mapFilter |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment