shapelessex
package shapelessex
- Alphabetic
- Public
- Protected
Type Members
- trait Monoid[T] extends AnyRef
- trait MonoidSyntax[T] extends AnyRef
Value Members
- object ArityExercises extends AnyFlatSpec with Matchers with Section
Conversions between tuples and
HList
's, and between ordinary Scala functions of arbitrary arity and functions which take a single correspondingHList
argument allow higher order functions to abstract over the arity of the functions and values they are passedFacilities for abstracting over arity
Conversions between tuples and
HList
's, and between ordinary Scala functions of arbitrary arity and functions which take a single correspondingHList
argument allow higher order functions to abstract over the arity of the functions and values they are passedimport syntax.std.function._ import ops.function._ def applyProduct[P <: Product, F, L <: HList, R](p: P)(f: F) (implicit gen: Generic.Aux[P, L], fp: FnToProduct.Aux[F, L => R]) = f.toProduct(gen.to(p))
- object AutoTypeClassExercises extends AnyFlatSpec with Matchers with Section
Based on and extending
Generic
andLabelledGeneric
, Lars Hupel (@larsr_h) has contributed theTypeClass
family of type classes, which provide automatic type class derivation facilities roughly equivalent to those available with GHC as described in "A Generic Deriving Mechanism for Haskell".Automatic type class instance derivation
Based on and extending
Generic
andLabelledGeneric
, Lars Hupel (@larsr_h) has contributed theTypeClass
family of type classes, which provide automatic type class derivation facilities roughly equivalent to those available with GHC as described in "A Generic Deriving Mechanism for Haskell". There is a description of an earlier iteration of the Scala mechanism here, and examples of its use derivingShow
andMonoid
instances here and here for labelled coproducts and unlabelled products respectively.For example, in the
Monoid
case, once the general deriving infrastructure for monoids is in place, instances are automatically available for arbitrary case classes without any additional boilerplatetrait Monoid[T] { def zero: T def append(a: T, b: T): T } object Monoid extends ProductTypeClassCompanion[Monoid] { def mzero[T](implicit mt: Monoid[T]) = mt.zero implicit def booleanMonoid: Monoid[Boolean] = new Monoid[Boolean] { def zero = false def append(a: Boolean, b: Boolean) = a || b } implicit def intMonoid: Monoid[Int] = new Monoid[Int] { def zero = 0 def append(a: Int, b: Int) = a+b } implicit def doubleMonoid: Monoid[Double] = new Monoid[Double] { def zero = 0.0 def append(a: Double, b: Double) = a+b } implicit def stringMonoid: Monoid[String] = new Monoid[String] { def zero = "" def append(a: String, b: String) = a+b } object typeClass extends ProductTypeClass[Monoid] { def emptyProduct = new Monoid[HNil] { def zero = HNil def append(a: HNil, b: HNil) = HNil } def product[F, T <: HList](mh: Monoid[F], mt: Monoid[T]) = new Monoid[F :: T] { def zero = mh.zero :: mt.zero def append(a: F :: T, b: F :: T) = mh.append(a.head, b.head) :: mt.append(a.tail, b.tail) } def project[F, G](instance: => Monoid[G], to: F => G, from: G => F) = new Monoid[F] { def zero = from(instance.zero) def append(a: F, b: F) = from(instance.append(to(a), to(b))) } } } trait MonoidSyntax[T] { def |+|(b: T): T } object MonoidSyntax { implicit def monoidSyntax[T](a: T)(implicit mt: Monoid[T]): MonoidSyntax[T] = new MonoidSyntax[T] { def |+|(b: T) = mt.append(a, b) } }
The shapeless-contrib project also contains automatically derived type class instances for Scalaz, Spire and Scalacheck.
- object CoproductExercises extends AnyFlatSpec with Matchers with Section
shapeless has a Coproduct type, a generalization of Scala's
Either
to an arbitrary number of choices.Coproducts and discriminated unions
shapeless has a Coproduct type, a generalization of Scala's
Either
to an arbitrary number of choices. Currently it exists primarily to supportGeneric
(see the next section), but will be expanded analogously toHList
in later releases. CurrentlyCoproduct
supports mapping, selection and unification - object CovariantHelper
- object ExtensibleRecordsExercises extends AnyFlatSpec with Matchers with Section
shapeless provides an implementation of extensible records modelled as
HLists
of values tagged with the singleton types of their keys.Extensible records
shapeless provides an implementation of extensible records modelled as
HLists
of values tagged with the singleton types of their keys. This means that there is no concrete representation needed at all for the keys. Amongst other things this will allow subsequent work onGeneric
to map case classes directly to records with their member names encoded in their element types.import shapeless._ ; import syntax.singleton._ ; import record._ val book = ("author" ->> "Benjamin Pierce") :: ("title" ->> "Types and Programming Languages") :: ("id" ->> 262162091) :: ("price" ->> 44.11) :: HNil
- object GenericExercises extends AnyFlatSpec with Matchers with Section
The
Iso
s of earlier shapeless releases have been completely reworked as the newGeneric
type, which closely resembles the generic programming capabilities introduced to GHC 7.2.Generic representation of (sealed families of) case classes
The
Iso
s of earlier shapeless releases have been completely reworked as the newGeneric
type, which closely resembles the generic programming capabilities introduced to GHC 7.2.Generic[T]
, whereT
is a case class or an abstract type at the root of a case class hierarchy, maps between values ofT
and a generic sum of products representation (HList
s andCoproduct
s), - object GenericHelper
- object HListExercises extends AnyFlatSpec with Matchers with Section
shapeless provides a comprehensive Scala
HList
which has many features not shared by other HList implementations.Heterogenous lists
shapeless provides a comprehensive Scala
HList
which has many features not shared by other HList implementations. - object HMapExercises extends AnyFlatSpec with Matchers with Section
Shapeless provides a heterogenous map which supports an arbitrary relation between the key type and the corresponding value type,
Heterogenous maps
Shapeless provides a heterogenous map which supports an arbitrary relation between the key type and the corresponding value type,
class BiMapIS[K, V] implicit val intToString = new BiMapIS[Int, String] implicit val stringToInt = new BiMapIS[String, Int] val hm = HMap[BiMapIS](23 -> "foo", "bar" -> 13) //val hm2 = HMap[BiMapIS](23 -> "foo", 23 -> 13) // Does not compile
- object Helper
- object LazyExercises extends AnyFlatSpec with Matchers with Section
Traversals and transformations of recursive types (eg.
First class lazy values tie implicit recursive knots
Traversals and transformations of recursive types (eg. cons lists or trees) must themselves be recursive. Consequently type class instances which perform such operations must be recursive values in turn. This is problematic in Scala at the both the value and the type levels: at the value level the issue is that recursive type class instances would have to be constructed lazily, whilst Scala doesn't natively support lazy implicit arguments; at the type level the issue is that during the type checking of expressions constructing recursive implicit values the implicit resolution mechanism would revisit types in a way that would trip the divergence checker.
The
Lazy[T]
type constructor and associated macro in shapeless addresses both of these problems in many cases. It is similar to Scalaz'sNeed[T]
and adds lazy implicit construction and suppression of divergence checking. This supports constructions such as... - object LensesExercises extends AnyFlatSpec with Matchers with Section
A combination of
LabelledGeneric
and singleton-typedSymbol
literals supports boilerplate-free lens creation for arbitrary case classesBoilerplate-free lenses for arbitrary case classes
A combination of
LabelledGeneric
and singleton-typedSymbol
literals supports boilerplate-free lens creation for arbitrary case classes// A pair of ordinary case classes ... case class Address(street : String, city : String, postcode : String) case class Person(name : String, age : Int, address : Address) // Some lenses over Person/Address ... val nameLens = lens[Person] >> Symbol("name") val ageLens = lens[Person] >> Symbol("age") val addressLens = lens[Person] >> Symbol("address") val streetLens = lens[Person] >> Symbol("address") >> Symbol("street") val cityLens = lens[Person] >> Symbol("address") >> Symbol("city") val postcodeLens = lens[Person] >> Symbol("address") >> Symbol("postcode") val person = Person("Joe Grey", 37, Address("Southover Street", "Brighton", "BN2 9UA"))
- object Monoid extends ProductTypeClassCompanion[Monoid]
- object MonoidSyntax
- object PolyExercises extends AnyFlatSpec with Matchers with Section
Ordinary Scala function values are monomorphic.
Polymorphic function values
Ordinary Scala function values are monomorphic. shapeless, however, provides an encoding of polymorphic function values. It supports natural transformations, which are familiar from libraries like Scalaz
- object ShapelessLib extends Library
Shapeless is a type class and dependent type based generic programming library for Scala.
- object SingletonExercises extends AnyFlatSpec with Matchers with Section
Although Scala's typechecker has always represented singleton types for literal values internally, there has not previously been syntax available to express them, other than by [modifying the compiler][literaltype].
Singleton-typed literals
Although Scala's typechecker has always represented singleton types for literal values internally, there has not previously been syntax available to express them, other than by [modifying the compiler][literaltype]. shapeless adds support for singleton-typed literals via implicit macros.
- object SizedExercises extends AnyFlatSpec with Matchers with Section
shapeless provides collection types with statically known sizes.
Collections with statically known sizes
shapeless provides collection types with statically known sizes. These can prevent runtime errors such as those that would result from attempting to take the head of an empty list, and can also verify more complex relationships.
def row(cols : Seq[String]) = cols.mkString("\\"", "\\", \\"", "\\"") def csv[N <: Nat] (hdrs : Sized[Seq[String], N], rows : List[Sized[Seq[String], N]]) = row(hdrs) :: rows.map(row(_)) val hdrs = Sized("Title", "Author") val rows = List( Sized("Types and Programming Languages", "Benjamin Pierce"), Sized("The Implementation of Functional Programming Languages", "Simon Peyton-Jones") )
- object SizedHelper
- object TuplesHListExercises extends AnyFlatSpec with Matchers with Section
shapeless allows standard Scala tuples to be manipulated in exactly the same ways as
HList
sHList-style operations on standard Scala tuples
shapeless allows standard Scala tuples to be manipulated in exactly the same ways as
HList
s - object TypeCheckingExercises extends AnyFlatSpec with Matchers with Section
Libraries like shapeless which make extensive use of type-level computation and implicit resolution often need to provide guarantees that certain expressions *don't* typecheck.
Testing for non-compilation
Libraries like shapeless which make extensive use of type-level computation and implicit resolution often need to provide guarantees that certain expressions *don't* typecheck. Testing these guarantees is supported in shapeless via the
illTyped
macro,import shapeless.test.illTyped scala> illTyped { """1+1 : Boolean""" } scala> illTyped { """1+1 : Int""" } <console>:19: error: Type-checking succeeded unexpectedly. Expected some error. illTyped { """1+1 : Int""" }
- object TypeSafeCastExercises extends AnyFlatSpec with Matchers with Section
shapeless provides a
Typeable
type class which provides a type safe cast operation.Type safe cast
shapeless provides a
Typeable
type class which provides a type safe cast operation.cast
returns anOption
of the target type rather than throwing an exception if the value is of the incorrect type, as can happen with separateisInstanceOf
andasInstanceOf
operations.Typeable
handles primitive values correctly and will recover erased types in many circumstances - object addSize extends Poly2
- object size extends Poly1