-
Notifications
You must be signed in to change notification settings - Fork 533
Release notes: shapeless 2.0.0
This is the final release of shapeless-2.0.0. A detailed feature overview and a guide to migration from shapeless1.2.4 are available on the shapeless wiki.
A big "Thank You!" to everyone who has contributed to this release, either directly in code or by using and discussing it, by inviting me to talk about it, and especially by ignoring my advice that shapeless was experimental and should under no circumstances be used in production. In particular I would like to thank Mathias Doenitz (@sirthias) and Eric Torreborre (@etorreborre) for taking the plunge and using shapeless in Spray routing and Specs 2 respectively. I am also very grateful to Eugene Burmako (@xeno_by) for his work on Scala macros, implicit macros in particular, which have enabled much of what's new.
Code contributors for shapeless 2.0.0 are,
- Alois Cochard (@aloiscochard)
- Cody Allen (@fourierstrick)
- Dario Rexin (@evonox)
- George Leontiev (@folone)
- Johannes Rudolph (@virtualvoid)
- Joni Freeman (@jonifreeman)
- Julien Tournay (@skaalf)
- Kevin Wright (@thecoda)
- Lars Hupel (@larsr_h)
- Michael Donaghy
- Michael Pilquist (@mpilquist)
- Nikolas Evangelopoulos
- Stacy Curl
- Stephen Compall (@S11001001)
- Travis Brown (@travisbrown)
Many thanks to all of you and everyone else who has contributed ideas, enthusiasim and encouragement.
There are a large number of new features, refactorings and bugfixes in shapeless 2.0.0. The features which were present in the 2.0.0-M1 preview release are repeated further below. The following summarizes the most significant changes between 2.0.0-M1 and this 2.0.0 final release.
- Added discriminated (ie. labelled) unions which have the same relationship
to
Coproducts
that shapeless records have toHList
s. As with records, the selectors are encoded by intersecting the singleton type of the label with the value type and so have no runtime footprint.
- Added an encoding of useful singleton types for
Symbol
literals.
- Added the LabelledGeneric type class which maps between (sealed families) of case classes and discriminated unions of records (ie. labelled sums of labelled products).
-
Lens improvements,
- Lens selector paths can now be given in terms of
Symbols
corresponding to member names rather thanNat
indices (thanks to Julien Tournay). - Added recordLens focussing on named fields of an extensible record (thanks to Stephen Compall).
- Added hlistSelectLens focussing on HList elements selected by type (thanks to Stephen Compall).
- The lens builder is now
lens[T] >> ...
rather thanLens[T] >> ...
.
- Lens selector paths can now be given in terms of
-
Improvements in the
TypeClass
infrastucture (joint work with Lars Hupel),- Clearer separation between
ProductTypeClass
(supporting type classes which are well-defined for product types only) and the generalTypeClass
(which supports sums of products). - Added
LabelledTypeClass
andLabelledProductTypeClass
which supply field and constructor name information to instances. - A (suppressible) warning is now generated on attempting to derive a type class instance for a single member of a sealed family of case classes.
- Clearer separation between
-
Added the Lazy type constructor which supports the lazy materialization of implicit values, hence the implicit creation of recursive implicit values (aka lazy implicit knot tying).
- Added TypeCase supporting the creation of
Typeable
-based extractors for use in pattern matches (thanks to Stacy Curl for the idea).
-
Various
HList
,Coproduct
and extensible record improvements,- Added constraint to prevent generation of spurious
Transposer
instances (thanks to Travis Brown). - Added
zipWith
toHList
, which zips a pair ofHList
s using aPoly2
(thanks to Stacy Curl). - Added
zipWithKeys
toHList
andCoproduct
, which yields a record/ discriminated union given a list of singleton-typed key names (thanks to Cody Allen) - Added
FieldPoly
which allows polymorphic functions to be indexed by record/union labels (thanks to Dario Rexin). - Added
Typeable
instance forCoproduct
.
- Added constraint to prevent generation of spurious
-
Added type-parametrized factory methods to the companion objects of all shapeless type classes, allowing instances to be acquired explictly without the use of (and attendant loss of precision with)
implicitly
. -
Various namespacing tweaks,
- The generic
Zipper
has be repackaged into ops and syntax modules for consistency the rest of the library. - The
Nat
type_0
is now aliased inshapeless.nat
for consistency with the other fully appliedNat
types. - The
Witness
implicits forNat
have been moved to theWitness
companion object so that they are accessible in contexts which would previously have required an import ofNat._
(thanks to Travis Brown).
- The generic
-
New test utilities,
- Added
showType
which renders a type or the type of an expression using Scala's reflection infrastructure. - Added
sameTyped
which compiles iff two expressions are of the same type. - Factored upteen definitions of
typed
out of the existing tests.
- Added
-
Build improvements,
- Complete reworking of the compile-time boilerplate generation infrastructure using string interpolation (thanks to Kevin Wright).
- Replaced dependency on scala-compiler with scala-reflect in shapeless-core (thanks to Johannes Rudolph).
New features and enhancements which were previously announced in the shapeless 2.0.0-M1 preview release included,
-
Scala 2.10.2 or later is now required. The advantages offered by implicit macros are so significant that all current and future shapeless development has committed to them.
Regrettably this means that shapeless-1.2.4 will very likely be the last release for Scala 2.9.x. It might be possible to backport some of the cosmetic changes to Scala 2.9.x, but I'd like to gauge the level of interest in continued support for older Scala releases before embarking on that. It might also be feasible to backport the major new features via a compiler plugin for Scala 2.9.x. Anyone interested in contributing to or sponsoring such work should [get in touch with me](mailto:[email protected]).
-
HList
-style operations are now available directly on native Scala tuples. This supports a wide variety of tuple manipulation operations which would otherwise be extremely tedious to implement manually. Examples can be found here and here. -
shapeless's
Iso
s 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). Values ofGeneric
for a given case class are materialized using an implicit macro, allowing a wide variety of structural programming problems to be solved with no or minimal boilerplate.In particular the existing [lens][lenses], [Scrap Your Boilerplate][sybclass] and [generic zipper][zipper] implementations are now available for any case class family ([recursive families included] [recursive]) without any additional boilerplate being required.
-
Based on and extending
Generic
, Lars Hupel has contributed theTypeClass
type class, which provides 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 the Scala mechanism here, and examples of its use derivingShow
andMonoid
instances here and here. The shapeless-contrib project also contains automatically derived type class instances for Scalaz, Spire and Scalacheck. -
Support has been added for working directly with singleton-typed literal values in Scala. Although Scala's typechecker has always represented these types internally, there has not previously been syntax available to express them, other than by modifying the compiler. This omission has been remedied by the use of implicit macros.
Singleton types bridge the gap between the value level and the type level and hence allow the exploration in Scala of techniques which would typically only be available in languages with support for full-spectrum dependent types. The latest iteration of shapeless records (see next bullet) makes a start on that, and the [examples in the tests][singletons] illustrate other possibilities.
-
As a first application of singleton-typed literals, shapeless records are now represented as
HList
s 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.Joni Freeman contributed an [updateWith][updatewith] operation. His library [sqltyped][sqltyped] [makes extensive use][sqltypedeg] of shapeless records.
-
The same implicit macro conversion mechanism which allows literal values to be converted to their singleton-typed equivalents is now also used to allow Int literals to be used where
Nat
values were previously required. Amongst other things, this allows HLists and tuples to be indexed using Ints. -
The library's namespace has been reorganized to bring it into better alignment with the other typelevel projects, Scalaz and Spire, and to reduce general clutter. See the migration guide for more details.
- Extension methods are now brought into scope by importing from an object
in the
shapeless.syntax
package (eg.import shapeless.syntax.singleton_
to import singleton type related extension methods). Extensions to standard Scala types can typically be found undershapeless.syntax.std
(eg.import shapeless.syntax.std.tuple._
). - Type classes and the implicits which materialize them are now imported
from the
shapeless.ops
package (eg.import shapeless.ops.hlist._
). - The previous shapeless convention of providing two variants of all type
classes, one with result types as members and one (with an
Aux
suffix) with result types as additional type parameters, has been refined. Now only the definition with type members is provided as a first-class trait or class, and the additional type parameter variant is defined via a type alias in the former's companion object. This results in a significantly smaller number of class files and also simplifies implicit resolution in some cases. - The
Poly
andCase
name conventions have been aligned with the new shapeless type class name convention. - The internals of Poly had (ironically) a large amount of arity specific/restricted artefacts. These have now been largely eliminated, yielding a more consistent structure.
- The type classes and extension methods for converting between functions
of multiple arguments and functions with a single
HList
argument have been renamed more transparently. - All implict definitions now have explicit result types, which should result in improved compile times.
- Extension methods are now brought into scope by importing from an object
in the
-
Various improvements to
HList
,- Added
zipConst
to zip anHList
with a constant (thanks to Cody Allen). - The base case for
removeAll
is nowHNil
allowing removals to be more uniform where the list of removed types is a type variable which might beHNil
(thanks to Michael Donaghy). - Added the
SubtypeUnifier
type class for normalizing subtypes of a given type in an HList to that type (thanks to Travis Brown) - Some unexpected
Filter
type class instances are no longer created (thanks Travis Brown). - The
HNil
trait is now sealed, eliminating non-exhaustiveness warnings in pattern matching. -
zipped
andunzipped
have been renamed tozip
andunzip
for consistency with the corresponding new operations provided for tuples, which are so-named to avoid clashing with the preexistingzipped
onTuple2
andTuple3
. - Added minimally witnessed instances for
toList[Any]
andtoArray[Any]
. - Added
HKernel
, an attempt to reduce the number of implicit witnesses required to perform operations onHList
s whose elements share a common outer type constructor.
- Added
-
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 now supported via the illTyped macro, and all tests have been updated to use it where appropriate.
-
The Sized type is now a value class, eliminating much of its runtime overhead.
-
Polymorphic methods can now be automatically converted to polymorphic function values.
-
Nat
additions includingMin
andPow
type classes and type level factorial and gcd examples (thanks to George Leontiev) -
New and improved examples: the type class instance packing and unpacking example now provides completely automatic unpacking as well as packing; and an example illustrating the use of singleton types and path dependent types to encode things normally only expressible in full spectrum dependently typed languages has been added.
There have also been many improvements to the build,
- Support for Scala 2.11.x has been moved to its own branch.
- Snapshot builds of master and the scala-2.11.x branch are now built and published automatically using Travis CI
- shapeless is now built with SBT 0.13.2.
- The build now uses the sbt-buildinfo and sbt-git plugins
to provide useful runtime build information (see
shapeless.BuildInfo
), and the sbt-release plugin is used to prepare releases. - The sbt-osgi plugin is now used to add OSGi metadata to the core library jar (thanks to Michael Pilquist).
- Whilst the examples are not strictly speaking tests, they are canaries for
potential issues, and a
run-all
SBT task has been added to support verifying that they execute without runtime errors. - A
.jvmopts
file has been added to the root of the project to provide a sensible configuration for the sbt-extras SBT launcher script. - Added 'import shapeless. _ ' as a console initial command.