wheaties / autolifts   0.7

Apache License 2.0 GitHub

Automatic functional lifting, mapping and folding.

Scala versions: 2.12 2.11


A dependently typed library for auto lifting and auto mapping of functions based on category theory but exposing an api that works in harmony with the standard Scala library.

Build Status Join the chat at https://gitter.im/wheaties/AutoLifts


AutoLifts is organized in a multi-project structure. The following modules are available for download:

The core module is a dependency of algebird, cats and scalaz. While it forms the backbone of AutoLifts and can be downloaded, it is not a standalone project. Subprojects such as docs and bench are for reference only.


The current released branch is 0.7 and compiled against Scala version 2.11 and 2.12. If using SBT add the following to the build definition:

libraryDependencies += "com.github.wheaties" %% "autolift-[backend]" % "0.7"

where "backend" is one of algebird, cats or scalaz. As stated above, core will be downloaded as a dependency.

Due note, the api will be subject to change as the library develops and progresses to a 1.0 release. We do not, however, expect there to be any fundamental changes to functionality. Also of note, we expect that the majority of common use items will remain a permanent fixture from this point forward, i.e. liftMap, liftFlatMap, etc.


A generalization on the concept of lifting such that functions can be lifted to arbitrarily deep nestings and stacks of Functors, Applicatives, Monads and Traversables. Or, put another way, adds a more powerful map, flatMap, and fold that figures out where the best application site is based upon the type of the function. This functionality is exposed via syntax extensions and auto-lifting contexts.

For example, working with a nested type structure, syntax extensions make the following possible:

scala> def addOne(x: Int) = x + 1

scala> val in = Option(List(1, 2, 3))
scala> in liftMap addOne
res0: Option[List[Int]] = Some(List(2, 3, 4))

or alternatively the same could be accomplished by wrapping a function in a reusable context:

scala> val liftedOne = liftMap(addOne)
scala> liftedOne(List(1, 2, 3))
res1: List[Int] = List(2, 3, 4)

scala> liftedOne(List(Option(1), None))
res2: List[Option[Int]] = List(Some(2), None)