typeless
Some typeclasses inspired and powered by shapeless
Find[L <: HList, A]
Will allow to find a type A
in an HList
L
, if the type is not present it returns None
, otherwise Some[A]
Subset[L <: HList,S <: HList]
Similar to Find
, but for a group of elements, if all the elements of the S
are present in L
it returns Some[S]
otherwise None
ListToHList[L, H < HList]
Converts a List[L]
to an Option[HList]
. The ListToHList
implicit class exposes two features.
.toProduct[A]
: convert List[L]
to an Option[A]
.
.findByType[B]
: find type B
within List[L]
import ListToHList.Ops
sealed trait A
case class B() extends A
case class C() extends A
case class D(b: B, c: C)
val listA: List[A] = List(B(), C())
listA.toProduct[D] === Some(D(B(), C()))
listA.findByType[B] === Some(B())
Convert[L <: Coproduct, S <: Coproduct]
For Coproducts L
and S
, Convert
takes a value of type L
and converts it to type S
.
example
type A = String :+: Double :+: CNil
type B = Double :+: String :+: List[Int] :+: CNil
Coproduct[A]("test").convert[B] === Some(Coproduct[B]("test"))
CoproductToHList[C <: Coproduct, L <: HList]
For a Seq
of Coproducts C
, convert to HList
of type L
example
type A = Int :+: String :+: CNil
type L = String :: Int :: HNil
Seq(Coproduct[A](1), Coproduct[A]("a")).toHList[L] === Some("a" :: 1 :: HNil))
case class Foo(i:Int, s:String)
Seq(Coproduct[A](1), Coproduct[A]("a")).toHList[Foo] === Some(Food("a", 1))
SelectFunctions[L <: HList, FF <: HList]
Takes an HList
of functions FF
and an HList
of potential arguments Context
. It applies the arguments to the functions for which all the arguments are present. It returns an HList
with the results. It will not compile if there is a function that cannot be applied.
example
val functions =
{ (x: String, i: Int, d: Double) => d.toInt * i } ::
{ (x: String, i: Int) => s"$x + $i" } ::
{ (x: String, s: Char, i: Int) => i.toDouble } ::
{ (x: String, s: Char, i: Int) => s.toInt + i * 2 + x.size } ::
{ (x: String) => x.size } ::
{ (x: Char) => x.toInt } ::
HNil
SelectFunctions.applyAll(1, hi)(functions) // won't compile
SelectFunctions.applyAll(hi, 'a', 1)(functions) == "hi + 1" :: 1.0 :: 101 :: 2 :: 97 :: HNil
FlattenFunctions[Context <: HList, FFF <: HList]
Takes an HList
of HLists
of functions and an HList
of potential arguments, and uses SelectFunctions[Context, FF]
to calculate the resulting HList
.
example
val functions1 =
{ (x: String, i: Int) => (x.size + i) } ::
{ (x: String, s: Char, i: Int) => (s.toInt + i * 2 + x.size) } ::
HNil
val functions2 =
{ (x: String, s: Char, i: Int) => (s.toInt + i + x.size) } ::
{ (i: Int) => i.toDouble } ::
HNil
val functions = functions1 ::
functions2 ::
HNil
FlattenFunctions.applyAll(1, "a", 'a')(functions) === 2 :: 1.0 :: 99 :: HNil
EqualsIgnoringFields[T]
It compares two cases classes excluding specific field names rather than types.
example:
import typeless.hlist.EqualsIgnoringFields.Ops
sealed trait Monarch
case class Butterflies(
_id: Long,
date: Long,
count: Int
) extends Monarch
case class Dictator(
_id: Long,
date: Long,
count: Int
) extends Monarch
val butterfliesStation1 = Butterflies(
_id = 1,
date = 1131,
count = 3
)
val butterfliesStation2 = Butterflies(
_id = 2,
date = 1131,
count = 2
)
// the two objects are the same if we ignore those two fields
assert(butterfliesStation1.equalsIgnoringFields(field => field == '_id || field == 'count)(butterfliesStation2))
// the two objects are different if not ignoring `count`
assert(!butterfliesStation1.equalsIgnoringFields(_ == '_id)(butterfliesStation2))
// the two objects are different, period
assert(butterfliesStation1 != butterfliesStation2)
Getting started
Scala 2.11/2.12
libraryDependencies += "ai.x" %% "typeless" % "0.6.0"