Code Monkey home page Code Monkey logo

shapeless's Introduction

shapeless: generic programming for Scala

shapeless is a type class and dependent type based generic programming library for Scala. It had its origins in several talks by Miles Sabin (@milessabin), given over the course of 2011, on implementing scrap your boilerplate and higher rank polymorphism in Scala. Since then it has evolved from being a resolutely experimental project into a library which, while still testing the limits of what's possible in Scala, is being used widely in production systems wherever there are arities to be abstracted over and boilerplate to be scrapped.

Discord Gitter Maven Central Scala.js

Projects which use shapeless

There is a wide variety of projects which use shapeless in one way or another ... see the incomplete list of projects for ideas and inspiration. If you are using shapeless and your project isn't listed yet, please add it.

Finding out more about the project

The feature overview for shapeless-2.0.0 provides a very incomplete introduction to shapeless. Additional information can be found in subsequent release notes. If you are upgrading from shapeless-2.0.0 you will find the migration guide useful. We're not satisfied with the current state of the documentation and would love help in improving it. You can find an excellent guide to Shapeless here: The Type Astronaut's Guide to Shapeless.

shapeless is part of the Typelevel family of projects. It is an Open Source project under the Apache License v2, hosted on github. Binary artefacts are published to the Sonatype OSS Repository Hosting service and synced to Maven Central.

Most discussion of shapeless and generic programming in Scala happens on the #shapless channel of the Typelevel Discord. There is also a mailing list and Gitter, but these are largely dormant now that most activity has moved to Discord. Questions about shapeless are often asked and answered under the shapeless tag on StackOverflow. Some articles on the implementation techniques can be found on Miles's blog, and Olivera, Moors and Odersky, Type Classes as Object and Implicits is useful background material.

Participation

The shapeless project supports the Scala Code of Conduct and wants all of its channels (mailing list, Gitter, IRC, github, etc.) to be welcoming environments for everyone.

Whilst shapeless is a somewhat "advanced" Scala library, it is a lot more approachable than many people think. Contributors are usually available to field questions, give advice and discuss ideas on the #shapeless Discord channel, and for people wanting to take their first steps at contributing we have a selection of open issues flagged up as being good candidates to take on. No contribution is too small, and guidance is always available.

Using shapeless

Binary release artefacts are published to the Sonatype OSS Repository Hosting service and synced to Maven Central. Snapshots of the main branch are built using GitHub actions and automatically published to the Sonatype OSS Snapshot repository.

Try shapeless with an Ammonite instant REPL

The quickest way to get to a REPL prompt with the latest version of shapeless on the class path is to run the provided "try shapeless" script, which has no dependencies other than an installed JDK. This script downloads and installs coursier and uses it to fetch the Ammonite REPL and the latest version of shapeless. It then drops you immediately into a REPL session,

% curl -s https://raw.githubusercontent.com/milessabin/shapeless/main/scripts/try-shapeless.sh | bash
Loading...
Compiling (synthetic)/ammonite/predef/interpBridge.sc
Compiling (synthetic)/ammonite/predef/replBridge.sc
Compiling (synthetic)/ammonite/predef/DefaultPredef.sc
Compiling /home/miles/projects/shapeless/(console)
Welcome to the Ammonite Repl 1.6.8
(Scala 2.13.1 Java 1.8.0_212)
If you like Ammonite, please support our development at www.patreon.com/lihaoyi
@ 23 :: "foo" :: true :: HNil 
res0: Int :: String :: Boolean :: HNil = 23 :: "foo" :: true :: HNil

@ Bye!
%

shapeless-2.3.3 with SBT

To include the Sonatype repositories in your SBT build you should add,

resolvers ++= Seq(
  Resolver.sonatypeRepo("releases"),
  Resolver.sonatypeRepo("snapshots")
)

Builds are available for Scala 2.11.x, 2.12.x and 2.13.x. The main line of development for shapeless 2.3.3 is Scala 2.13.2.

scalaVersion := "2.13.5"

libraryDependencies ++= Seq(
  "com.chuusai" %% "shapeless" % "2.3.3"
)

For using snapshots of Shapeless you should add,

scalaVersion := "2.13.5"

libraryDependencies ++= Seq(
  "com.chuusai" %% "shapeless" % "2.4.0-SNAPSHOT"
)

shapeless-2.3.3 with Maven

shapeless is also available for projects using the Maven build tool via the following dependency,

<dependency>
  <groupId>com.chuusai</groupId>
  <artifactId>shapeless_2.13</artifactId>
  <version>2.3.3</version>
</dependency>

Older releases

Please use a current release if possible. If unavoidable, you can find usage information for older releases on the shapeless wiki.

Building shapeless

shapeless is built with SBT 1.3.10 or later, and its main branch is built with Scala 2.13.2 by default but also cross-builds for 2.11.12 and 2.12.12.

Contributors

shapeless's People

Contributors

alexarchambault avatar aloiscochard avatar aryairani avatar atry avatar ceedubs avatar clhodapp avatar dmytromitin avatar dwijnand avatar fommil avatar fthomas avatar guersam avatar jeremyrsmith avatar jorokr21 avatar kazchimo avatar kevinwright avatar larsrh avatar mandubian avatar milessabin avatar mpilquist avatar pgrandjean avatar reactormonk avatar retronym avatar scala-steward avatar som-snytt avatar stacycurl avatar systemfw avatar teldosas avatar travisbrown avatar wheaties avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shapeless's Issues

Mapping over HLIST with poly from different input type to same return type does not compile

Hi,

writing a poly function like this:

object testfun extends Poly1 {
  implicit val atString = at[String](identity)
  implicit val atInt = at[Int](_.toString)
  implicit def default[A] = at[A](identity)
}

and trying to map over an HList leads to following error:

val hlist = 1 :: "foo" :: 1.5 :: HNil

hlist map testfun

[error] /Users/dario.rexin/projects/shapeless-foo/src/main/scala/Main.scala:15: could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[main.scala.Test.testfun.type,shapeless.::[Int,shapeless.::[String,shapeless.::[Double,shapeless.HNil]]]]
[error]   hlist map testfun

toList on shapeless HList fails when resulting existential type too complex

See the stackoverflow post

Given the following:

class R[T]

class A
class B
class C

This works:

val s1 = new R[A] :: new R[B] :: HNil
val r1 = s1.toList
// r1 of type: List[R[_ >: A with B]]

While this does not:

val s2 = new R[A] :: new R[B] :: new R[C] :: HNil
val r2 = s2.toList
// could not find implicit value for parameter toList:
// shapeless.ToList[shapeless.::[R[A],
// shapeless.::[R[B],shapeless.::[R[C],shapeless.HNil]]],Lub]

Workaround:

val r3 = s2.toList[R[_]]
// or
val r4 = s2.toList[R[_ >: A with B with C]]

Problematic settings in shapeless build for cross-publishing

The discussion on scala-internals and on SI-8425 raised concerns about shapeless cross-version publishing settings. In particular, the 1.2.4 got published with wrong suffix when published against Scala 2.11 milestones/rcs. I looked briefly at build definition and found a few problematic lines.

This is not needed:

crossVersion        <<= isSnapshot { s => if(s) CrossVersion.full else CrossVersion.binary }

The defaults in sbt 0.13 handle SNAPSHOTS, RCs, milestones, etc.

Then this is problematic:

      scalaVersion        := "2.10.3",
      scalaBinaryVersion  := "2.10.3",

This wil fail if one uses ++ 2.11.0-RC command in sbt console. Sbt will change scalaVersion to be 2.11.0-RC1 but scalaBinaryVersion will remain 2.10.3. Scala binary version must be always derived from scalaVersion.
Again, sbt 0.13.x has the right defaults and setting scalaBinaryVersion manually is not needed.

Missing Type limit on -> for a Record's Field

This is more of a feature improvement than a proper bug. In the example of Record in the Readme, we can see:

object author extends Field[String]
object title extends Field[String]
object price extends Field[Double]
object inPrint extends Field[Boolean]

 val book = (author -> "Benjamin Pierce") ::
      (title -> "Types and Programming Languages") ::
      (price -> 44.11) :: HNil

There is nothing stoping me from writing:

    val book = (author -> "Benjamin Pierce") ::
      (title -> "Types and Programming Languages") ::
      (price -> "test") :: HNil

When I then do:

val pr: Double = book.get(price) 

it won't compile (that's why it's not a bug), but it gives a quite funny error:

  • could not find implicit value for parameter selector: shapeless.Selector[shapeless.::[(test.author.type, String),shapeless.::[(test.title.type, String),shapeless.::[(test.price.type, String),shapeless.HNil]]],(test.price.type, test.price.valueType)]
  • not enough arguments for method get: (implicit selector: shapeless.Selector[shapeless.::[(test.author.type, String),shapeless.::[(test.title.type, String),shapeless.::[(test.price.type, String),shapeless.HNil]]],(test.price.type, test.price.valueType)])test.price.valueType. Unspecified value parameter selector.

Again, that's not a bug, but it's not the most user friendly way to break I think (if you disagree, just close the bug ;) ).
I do not know of an easy way to limit the -> type signature, but I was thinking that there could be another "safe" method in Field to assign values, something like:

  trait Field[T] extends FieldAux {
    type valueType = T
    def :=(value: T) = this -> value
  }

This way:

    val book = (author := "Benjamin Pierce") ::
      (title := "Types and Programming Languages") ::
      (price := "test") :: HNil

would break on the price assignment, with a more meaningful message:

type mismatch; found : String("test") required: Double

Better Docs

Is it possible to have better documentation on Shapeless.

No implicit Generic[A] available if A is defined in an expression

Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import shapeless._
import shapeless._

scala> { case class Foo(x: Int, y: String); implicitly[Generic[Foo]] }
<console>:11: error: could not find implicit value for parameter e: shapeless.Generic[Foo]
              { case class Foo(x: Int, y: String); implicitly[Generic[Foo]] }
                                                             ^

scala> def foo = { case class Foo(x: Int, y: String); implicitly[Generic[Foo]] }
<console>:10: error: could not find implicit value for parameter e: shapeless.Generic[Foo]
       def foo = { case class Foo(x: Int, y: String); implicitly[Generic[Foo]] }
                                                                ^

scala> case class Foo(x: Int, y: String); implicitly[Generic[Foo]]
defined class Foo
res1: shapeless.Generic[Foo] = $1$$1@7b63a14

One common use case for this is writing tests with ScalaTest or Spec2. Something like:

class MyTest extends WordSpec {
  "my code" should {
    case class Foo(x: Int, y: String)
    "do something interesting" in {
      ...
    }
  }
}

Add apply and at methods to Sized.

Sized should have at and apply methods analogous to those on HList: they should yield the _n_th element of the collection iff it has at least n elements. For HLists we have,

scala> val l = 1 :: 2 :: 3 :: 4 :: HNil                                                                                                     
l: shapeless.::[Int,shapeless.::[Int,shapeless.::[Int,shapeless.::[Int,shapeless.HNil]]]] = 1 :: 2 :: 3 :: 4 :: HNil                        

scala> l(0)                                                                                                                                 
res0: Int = 1                                                                                                                               

scala> l(3)
res2: Int = 4                                                                                                                               

scala> l(4)
<console>:15: error: could not find implicit value for parameter at: shapeless.ops.hlist.At[shapeless.::[Int,shapeless.::[Int,shapeless.::[Int,shapeless.::[Int,shapeless.HNil]]]],nat_$macro$4.N]
              l(4)
               ^

The same would be useful for Sized.

OSGI settings place publish-local jar in .ivy2/.../bundles/

The OSGI settings in Build.scala cause a SNAPSHOT build from publish-local to place jar files in .ivy2/.../bundles/. The expectation is .ivy2/.../jars/. I did not easily find a way to depend on the OSGI bundle with sbt. My workaround is to comment out osgiSettings and lines beginning with OsgiKeys.

Could OSGI publishing be moved to a different target? Wanting to try the SNAPSHOT should be easier from publish-local. Thanks.

Release for Scala 2.10-RC1

We'd like to release spray for Scala 2.10-RC1 in the next days and shapeless is one of our (very few) dependencies. If you publish a fresh build we'd be ready to go...

Missing type declarations crash implicit search in SingletonTypeMacros

I'm guessing it's an issue in shapeless.SingletonTypeMacros.
Modified test from the codebase:

class Test {
  import shapeless._

  trait Rel[T] {
    type Out
  }

/*    val wTrue = Witness(true)
    type True = wTrue.T
    val wFalse = Witness(false)
    type False = wFalse.T
*/


  object Rel {
    implicit def relTrue:  Rel[True]  { type Out = Int  } = new Rel[True]  { type Out = Int }
    implicit def relFalse: Rel[False] { type Out = String } = new Rel[False] { type Out = String }
  }
  def test {
    def check(w: WitnessWith[Rel])(v: w.Out) = v
    check(true)("foo")
  }
}

crashes with

error: exception during macro expansion: 
scala.reflect.macros.TypecheckException: implicit search has failed. to find out the reason, turn on -Xlog-implicits
    at scala.reflect.macros.runtime.Typers$$anonfun$inferImplicitValue$2.apply(Typers.scala:38)
    at scala.reflect.macros.runtime.Typers$$anonfun$inferImplicitValue$2.apply(Typers.scala:38)
    at scala.tools.nsc.typechecker.Implicits$class.fail$1(Implicits.scala:107)
    at scala.tools.nsc.typechecker.Implicits$class.inferImplicit(Implicits.scala:113)
    at scala.tools.nsc.Global$$anon$1.inferImplicit(Global.scala:493)
    at scala.reflect.macros.runtime.Typers$class.inferImplicitValue(Typers.scala:38)
    at scala.reflect.macros.runtime.Context.inferImplicitValue(Context.scala:6)
    at scala.reflect.macros.runtime.Context.inferImplicitValue(Context.scala:6)
    at shapeless.SingletonTypeMacros$class.convertInstanceImpl(singletons.scala:147)
    at shapeless.SingletonTypeMacros$$anon$1.convertInstanceImpl(singletons.scala:278)
    at shapeless.SingletonTypeMacros$.convertInstanceImpl1(singletons.scala:286)

org.scalatest#scalatest_2.10;2.0.M4: not found - SBT 0.12.1?

https://github.com/harrah/xsbt/wiki/ChangeSummary_0.12.0

[warn] ==== Sonatype Snapshots: tried
[warn] http://oss.sonatype.org/content/repositories/snapshots/com/chuusai/shapeless_2.10/1.2.3-SNAPSHOT/shapeless_2.10-1.2.3-SNAPSHOT.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scalatest#scalatest_2.10;2.0.M4: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: FAILED DOWNLOADS ::
[warn] :: ^ see resolution messages for details ^ ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.chuusai#shapeless_2.10;1.2.3-SNAPSHOT!shapeless_2.10.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
sbt.ResolveException: unresolved dependency: org.scalatest#scalatest_2.10;2.0.M4: not found

Compilation times of record operations could be improved

As a simple performance test consider a class below. Uncomment line by line and measure the build time.

object Test {
  val r =
    ("k01" ->> 1) :: ("k02" ->> 1) :: ("k03" ->> 1) :: ("k04" ->> 1) :: ("k05" ->> 1) ::
    ("k06" ->> 1) :: ("k07" ->> 1) :: ("k08" ->> 1) :: ("k09" ->> 1) :: ("k10" ->> 1) ::
    ("k11" ->> 1) :: ("k12" ->> 1) :: ("k13" ->> 1) :: ("k14" ->> 1) :: ("k15" ->> 1) ::
    ("k16" ->> 1) :: ("k17" ->> 1) :: ("k18" ->> 1) :: ("k19" ->> 1) :: ("k20" ->> 1) ::
    ("k21" ->> 1) :: ("k22" ->> 1) :: ("k23" ->> 1) :: ("k24" ->> 1) :: ("k25" ->> 1) ::
    ("k26" ->> 1) :: ("k27" ->> 1) :: ("k28" ->> 1) :: ("k29" ->> 1) :: ("k30" ->> 1) ::
    ("k31" ->> 1) :: ("k32" ->> 1) :: ("k33" ->> 1) :: ("k34" ->> 1) :: ("k35" ->> 1) :: HNil

  // r get "k01"
  // r get "k02"
  // r get "k03"
  // r get "k04"
  // r get "k05"
  // r get "k10"
  // r get "k20"
}

Times on my machine with current Shapeless.

// r get "k01"  // 1s
// r get "k02"  // 4s
// r get "k03"  // 7s
// r get "k04"  // 10s
// r get "k05"  // 12s
// r get "k10"  // 21s
// r get "k20"  // 30s

Using Witnesses is more expensive than objects as keys.

object k01; object k02; object k03; object k04; object k05; object k06; object k07; object k08;
object k09; object k10; object k11; object k12; object k13; object k14; object k15; object k16;
object k17; object k18; object k19; object k20; object k21; object k22; object k23; object k24;
object k25; object k26; object k27; object k28; object k29; object k30; object k31; object k32;
object k33; object k34; object k35

object Test2 {
  val r =
    (k01 -> 1) :: (k02 -> 1) :: (k03 -> 1) :: (k04 -> 1) :: (k05 -> 1) ::
    (k06 -> 1) :: (k07 -> 1) :: (k08 -> 1) :: (k09 -> 1) :: (k10 -> 1) ::
    (k11 -> 1) :: (k12 -> 1) :: (k13 -> 1) :: (k14 -> 1) :: (k15 -> 1) ::
    (k16 -> 1) :: (k17 -> 1) :: (k18 -> 1) :: (k19 -> 1) :: (k20 -> 1) ::
    (k21 -> 1) :: (k22 -> 1) :: (k23 -> 1) :: (k24 -> 1) :: (k25 -> 1) ::
    (k26 -> 1) :: (k27 -> 1) :: (k28 -> 1) :: (k29 -> 1) :: (k30 -> 1) ::
    (k31 -> 1) :: (k32 -> 1) :: (k33 -> 1) :: (k34 -> 1) :: (k35 -> 1) :: HNil

  // r get k01
  // r get k02
  // r get k03
  // r get k04
  // r get k05
  // r get k10
  // r get k20
}

Times on my machine with current Shapeless.

// r get k01  // 1s
// r get k02  // 2s
// r get k03  // 4s
// r get k04  // 5s
// r get k05  // 6s
// r get k10  // 9s
// r get k20  // 12s

Switching to

type FieldType[K, V] = (K, V)

improves compilation times.

// Witnesses as keys
// r get "k01"  // 1s
// r get "k02"  // 3s
// r get "k03"  // 5s
// r get "k04"  // 6s
// r get "k05"  // 7s
// r get "k10"  // 12s
// r get "k20"  // 16s

// Objects as keys
// r get k01  // 1s
// r get k02  // 2s
// r get k03  // 2s
// r get k04  // 3s
// r get k05  // 3s
// r get k10  // 5s
// r get k20  // 7s

Getting beyond that is perhaps not possible in Shapeless and further optimizations should be done in scalac?

HList Schema definition

It would be really useful (e.g. for JSON message definition) to be able to define an entire HList hierarchy in one statement, effectively an alternative to having lots of nested case classes.

Lenses compile time insanely slow

Hi,

I have about 70 lenses where about 60 of them are nested, all are used in the same class. The compile time on my project is about 10 minutes with these 70 lenses, and without them just a few seconds. Makes it impossible to use them.

Weaker bound needed on result type in shapeless 2.0.0-M2

The following gist by @milessabin shows an example of using implicit functions that are more specific than the return type for which they are used. In those cases a weaker bound on the result type is required hence, toJSON.Case[A] { type Result <: JValue }

The compiler will provide the following error if the weaker bound is missing:

type mismatch; found : st.Result required: org.json4s.JValue
(which expands to) org.json4s.JsonAST.JValue

https://gist.github.com/milessabin/6345757

Add ability to get field from record

I see a pattern emerging in transforming flat records into nested records. Example:

records.groupBy(_("groupId")).values.map { rs =>
  "groupId"   ->> rs.head("groupId")   ::
  "startDate" ->> rs.head("startDate") ::
  "children"  ->> rs                   :: HNil
}

We could save a step and access the field and value whole. It also removes some brittleness when reusing free-range singletons (reduce the chance of a typo).

records.groupBy(_("groupId")).values.map { rs =>
  rs.head.field("groupId")   ::
  rs.head.field("startDate") ::
  "children" ->> rs          :: HNil
}

Do you think this would be useful? What would be the best getter name, field or something else?

Include `_0` in `shapeless.nat`

Currently zero is located in a different namespace from other aliases, which results in inconsistency: shapeless._0 vs shapeless.nat._1. I suggest to at least include an according alias.

Binding naturals in hlist ops requires explicit import of shapeless.nat._

Consider this example:

import shapeless._

object Example {
  import shapeless.ops.hlist.{Prepend, Length, Split}

  def concat[F[_], K <: HList, L <: HList, KL <: HList, KLen <: Nat](fk: F[K], fl: F[L])(implicit
    prepend: Prepend.Aux[K, L, KL],
    lengthK: Length.Aux[K, KLen],
    split: Split.Aux[KL, KLen, (K, L)]
  ): F[KL] = ???
}

In order to call concat, the call site must explicitly import shapeless.nat._. Witness:

scala> val x = 1 :: HNil
x: shapeless.::[Int,shapeless.HNil] = 1 :: HNil

scala> val y = false :: HNil
y: shapeless.::[Boolean,shapeless.HNil] = false :: HNil

scala> Example.concat(Option(x), Option(y))
<console>:29: error: could not find implicit value for parameter lengthK: shapeless.ops.hlist.Length.Aux[shapeless.::[Int,shapeless.HNil],KLen]
              Example.concat(Option(x), Option(y))
                            ^

scala> import shapeless.nat._
import shapeless.nat._

scala> Example.concat(Option(x), Option(y))
scala.NotImplementedError: an implementation is missing
        at scala.Predef$.$qmark$qmark$qmark(Predef.scala:252)
        at Example$.concat(<console>:32)

shapless 2.10.3 depends on 2.10.2

This results in a cross version conflict:

[info] downloading http://repo1.maven.org/maven2/com/chuusai/shapeless_2.10.3/2.0.0-M1/shapeless_2.10.3-2.0.0-M1.jar ...
[info] [SUCCESSFUL ] com.chuusai#shapeless_2.10.3;2.0.0-M1!shapeless_2.10.3.jar(bundle) (534ms)
[info] downloading http://repo1.maven.org/maven2/com/chuusai/shapeless_2.10.2/2.0.0-M1/shapeless_2.10.2-2.0.0-M1.jar ...
[info] [SUCCESSFUL ] com.chuusai#shapeless_2.10.2;2.0.0-M1!shapeless_2.10.2.jar(bundle) (539ms)
[info] Done updating.
[error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/kirstin/src/scala/hello/}hello:
[error] com.chuusai:shapeless _2.10.3, _2.10.2
[trace] Stack trace suppressed: run 'last *:update' for the full output.
error Conflicting cross-version suffixes in: com.chuusai:shapeless

But importing only 2.10.2 in scala 2.10.3 results in a successful compile, but a bad symbolic reference when observed in the scala console.

error:
while compiling:
during phase: erasure
library version: version 2.10.3
compiler version: version 2.10.3
reconstructed args: -classpath /Users/kirstin/.ivy2/cache/com.google.inject/guice/jars/guice-1.0.jar:/Users/kirstin/.ivy2/cache/org.specs2/classycle/jars/classycle-1.4.1.jar:/Users/kirstin/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.10.3.jar:/Users/kirstin/.ivy2/cache/junit/junit/jars/junit-4.11.jar:/Users/kirstin/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.10.3.jar:/Users/kirstin/.ivy2/cache/org.pegdown/pegdown/jars/pegdown-1.2.1.jar:/Users/kirstin/.ivy2/cache/org.parboiled/parboiled-core/jars/parboiled-core-1.1.4.jar:/Users/kirstin/.ivy2/cache/org.ow2.asm/asm-util/jars/asm-util-4.1.jar:/Users/kirstin/src/scala/hello/target/scala-2.10/classes:/Users/kirstin/.ivy2/cache/org.scalaz/scalaz-core_2.10/bundles/scalaz-core_2.10-7.0.4.jar:/Users/kirstin/.ivy2/cache/com.beust/jcommander/jars/jcommander-1.27.jar:/Users/kirstin/.ivy2/cache/org.scala-sbt/test-interface/jars/test-interface-1.0.jar:/Users/kirstin/src/scala/hello/target/scala-2.10/test-classes:/Users/kirstin/.emacs.d/elpa/ensime-20131030.2303/lib/scala-compiler.jar:/Users/kirstin/.ivy2/cache/org.objenesis/objenesis/jars/objenesis-1.0.jar:/Users/kirstin/.ivy2/cache/org.scalatest/scalatest_2.10/jars/scalatest_2.10-2.0.1-SNAP.jar:/Users/kirstin/.ivy2/cache/org.hamcrest/hamcrest-core/jars/hamcrest-core-1.3.jar:/Users/kirstin/.ivy2/cache/org.scalacheck/scalacheck_2.10/jars/scalacheck_2.10-1.11.1.jar:/Users/kirstin/.ivy2/cache/org.scalaz/scalaz-effect_2.10/bundles/scalaz-effect_2.10-7.0.4.jar:/Users/kirstin/.emacs.d/elpa/ensime-20131030.2303/lib/scala-library.jar:/Users/kirstin/.ivy2/cache/org.parboiled/parboiled-java/jars/parboiled-java-1.1.4.jar:/Users/kirstin/.ivy2/cache/org.scala-lang/scala-compiler/jars/scala-compiler-2.10.3.jar:/Users/kirstin/.ivy2/cache/org.beanshell/bsh/jars/bsh-2.0b4.jar:/Users/kirstin/.ivy2/cache/org.mockito/mockito-core/jars/mockito-core-1.9.5.jar:/Users/kirstin/.ivy2/cache/org.specs2/specs2_2.10/jars/specs2_2.10-2.3.4.jar:/Users/kirstin/.ivy2/cache/aopalliance/aopalliance/jars/aopalliance-1.0.jar:/Users/kirstin/.ivy2/cache/org.ow2.asm/asm-tree/jars/asm-tree-4.1.jar:/Users/kirstin/.ivy2/cache/org.testng/testng/jars/testng-6.8.jar:/Users/kirstin/.ivy2/cache/org.ow2.asm/asm/jars/asm-4.1.jar:/Users/kirstin/.ivy2/cache/org.scalaz/scalaz-concurrent_2.10/bundles/scalaz-concurrent_2.10-7.0.4.jar:/Users/kirstin/.ivy2/cache/org.yaml/snakeyaml/jars/snakeyaml-1.6.jar:/Users/kirstin/.ivy2/cache/org.ow2.asm/asm-analysis/jars/asm-analysis-4.1.jar

== Expanded type of tree ==

ThisType(object $iw)

uncaught exception during compilation: scala.reflect.internal.Types$TypeError
scala.reflect.internal.Types$TypeError: bad symbolic reference. A signature in foo.class refers to term shapeless
in package which is not available.
It may be completely missing from the current classpath, or the version on

NewtypeExampes and LinearAlgebraExamples fail

in 71604f8

> run-main shapeless.examples.NewtypeExampes
[warn] Credentials file /Users/kenji/.ivy2/.credentials does not exist
[info] Running shapeless.examples.NewtypeExampes 
[error] (run-main) java.lang.ClassCastException: java.lang.String cannot be cast to shapeless.TypeOperators$Tagged
java.lang.ClassCastException: java.lang.String cannot be cast to shapeless.TypeOperators$Tagged
        at shapeless.TypeOperators$.newtype(typeoperators.scala:85)
        at shapeless.examples.NewtypeExampes$.MyString(newtype.scala:28)
        at shapeless.examples.NewtypeExampes$delayedInit$body.apply(newtype.scala:36)
        at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App$$anonfun$main$1.apply(App.scala:71)
        at scala.App$$anonfun$main$1.apply(App.scala:71)
        at scala.collection.immutable.List.foreach(List.scala:318)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
        at scala.App$class.main(App.scala:71)
        at shapeless.examples.NewtypeExampes$.main(newtype.scala:19)
        at shapeless.examples.NewtypeExampes.main(newtype.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
[trace] Stack trace suppressed: run last shapeless-examples/compile:run-main for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last shapeless-examples/compile:run-main for the full output.
[error] (shapeless-examples/compile:run-main) Nonzero exit code: 1
[error] Total time: 0 s, completed Apr 2, 2013 6:42:29 AM
> run-main shapeless.examples.LinearAlgebraExamples
[warn] Credentials file /Users/kenji/.ivy2/.credentials does not exist
[info] Running shapeless.examples.LinearAlgebraExamples 
[error] (run-main) java.lang.ClassCastException: scala.Tuple1$mcD$sp cannot be cast to shapeless.TypeOperators$Tagged
java.lang.ClassCastException: scala.Tuple1$mcD$sp cannot be cast to shapeless.TypeOperators$Tagged
        at shapeless.TypeOperators$.newtype(typeoperators.scala:85)
        at shapeless.examples.LinearAlgebraExamples$.Vector(linearalgebra.scala:61)
        at shapeless.examples.LinearAlgebraExamples$delayedInit$body.apply(linearalgebra.scala:68)
        at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App$$anonfun$main$1.apply(App.scala:71)
        at scala.App$$anonfun$main$1.apply(App.scala:71)
        at scala.collection.immutable.List.foreach(List.scala:318)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
        at scala.App$class.main(App.scala:71)
        at shapeless.examples.LinearAlgebraExamples$.main(linearalgebra.scala:24)
        at shapeless.examples.LinearAlgebraExamples.main(linearalgebra.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
[trace] Stack trace suppressed: run last shapeless-examples/compile:run-main for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last shapeless-examples/compile:run-main for the full output.
[error] (shapeless-examples/compile:run-main) Nonzero exit code: 1
[error] Total time: 0 s, completed Apr 2, 2013 6:42:35 AM

Add missing implicit annotations.

There are very many implicit arguments in shapeless without @implicitNotFound annotations. Adding them would make compiler errors more readable.

ProductLens is not a lens

The Lens category does not support a "fan-out" operation, sometimes called &&& and implemented as a method called ~ in shapeless.

&&& has the type (A ~> B) => (A ~> C) => (A ~> (B, C)) where ~> denotes the category. It is not possible to use the lens category here. While &&& is available on all arrows, the lens category is not an arrow. Consequently, the return result of the shapeless ~ method is not a lens, since it violates the lens law of retention.

Coincidentally, this can also be said about what is often called +++, which cannot be implemented on the lens category, however, I don't think this function is implemented in shapeless (I couldn't find it). I only note this point for possible future reference.
+++ has the type (A ~> B) => (C ~> D) => (Either[A, C] ~> Either[C, D])

I have expressed the lens data structure using the Haskell programming language and also represented as a more direct correspondence to the costate comonad coalgebra. This coalgebra gives rise to the lens laws (more directly) which are also implemented. I have reimplemented the shapeless ~ method as the haskell function (.&&&.) and directly transcribed its implementation error. I have then provided counter-examples using (.&&&.) on two lenses that then produces a value violating the law of retention. These counter-example values can be seen in the function violations, which holds all False values, indicating a violation of the lens law.

import Control.Applicative

data Costate a b =
  Costate {
    put ::
      a
      -> b
  , pos ::
      a
  }

copoint ::
  Costate a b
  -> b
copoint (Costate s g) =
  s g

newtype Lens a b =
  Lens {
    unL :: a -> Costate b a
  }

(.&&&.) ::
  Lens a b
  -> Lens a c
  -> Lens a (b, c)
Lens f .&&&. Lens g =
  Lens $ \a -> 
    let Costate sb gb = f a
        Costate sc gc = g a
    in Costate (\(p, q) -> put (g (sb p)) q) (gb, gc)

lawIdentity ::
  Eq a =>
  Lens a b
  -> a
  -> Bool
lawIdentity (Lens f) =
  (==) <*> copoint . f

lawRetention ::
  Eq b =>
  Lens a b
  -> a
  -> b
  -> Bool
lawRetention (Lens f) a =
  (==) <*> pos . f . put (f a)

lawDoubleSet ::
  Eq a =>
  Lens a b
  -> a
  -> b
  -> b
  -> Bool
lawDoubleSet (Lens f) a b1 b2 =
  let r = put (f a)
  in r b2 == put (f (r b1)) b2

fstL ::
  Lens (a, b) a
fstL =  
  Lens $ \(a, b) -> Costate (\a' -> (a', b)) a

sndL ::
  Lens (a, b) b
sndL =  
  Lens $ \(a, b) -> Costate (\b' -> (a, b')) b

x ::
  Lens (a, b) (a, a)
x =
  fstL .&&&. fstL

violation1 ::
  Bool
violation1 =
  lawRetention x (0, 7) (1, 0)

violation2 ::
  Bool
violation2 =
  lawRetention x (0, 7) (0, 1)

violation3 ::
  Bool
violation3 =
  lawRetention x (0, 7) (1, 2)

violations ::
  [Bool]
violations =
  [violation1, violation2, violation3]

Refuse to produce impossible Typeable instances

scala> implicitly[Typeable[Int => Int]]
res0: shapeless.Typeable[Int => Int] = shapeless.LowPriorityTypeable$$anon$1@1440bc05

It would be neat if there was some way to constrain dfltTypeable so that it wouldn't produce instances like this — that is, it would only produce instances for types derived from nongeneric classes.

Publish a 1.2.4 jar for scala 2.11.0-M3

Hi Miles,

I need to release a specs2 version for 2.11.0-M3 but I now depend on Shapeless... Can you please publish a jar for 2.11.0-M3? I hope that it's not too hard especially since I just rely on HLists for now.

Problem finding implicits for HNil.type

For quite some time I had a problem using maps and folds. I finally figured out it was because it could not find implicits that involve Int.type.

object test extends Poly1 {
  implicit def caseAll[O] = at[O] { entry => entry }
}

HNil.map(test)

Causes the following error:

could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[test.type,shapeless.HNil.type]

Changing the call of map to the following solves the problem:

(HNil:HNil).map(test)

Another workaround is to define an implicit for HNil.type:

implicit val hnil =
  new Mapper[test.type, HNil.type] {
    type Out = HNil.type
    def apply(l: HNil.type): Out = HNil
  }

It's very hard to notice this error because most implicits involving HList depend on the HNil implicits.

Not sure how this would be fixed. The result of a fold on an HNil becomes useless:

val one = true :: HNil
val two = one.foldRight(HNil)(test)
two.foldRight(HNil)(test)

The above code gives the following error:

could not find implicit value for parameter folder: shapeless.ops.hlist.RightFolder[shapeless.::[Boolean,shapeless.HNil.type],shapeless.HNil.type,test.NestedValidation.test.type]

It can be solved by calling foldRight like this:

  one.foldRight(HNil:HNil)(test)

HSet and/or new constraint request

Hi,
this is a quick question or feature request.

I wonder if it is possible to create something like a HSet. The task I want to accomplish is to have i.e. a method which need as a parameter a collection which holds at least(or just) one String and Int.

I read about HList constraints and perhaps it is possible to achieve this behavior with them. The BasisConstrains allows only parameters with one or more elements for each requested type.
I would need a constraint to allow any parameter which has at least one(or more) of each requested Type.

Something like:

type M = String :: Int :: HNil
def test[L <: HList : NewConstraint[M]#lambda](l:L) = true

works for

test(Car :: Person :: 23 :: "test" :: false) 

don't add minor version qualifiers for artefacts aimed at Scala 2.10 and above

Apart from anything else sbt can have issues with it:

[error] Modules were resolved with conflicting cross-version suffixes in {file:/…/blobstore/}client:
[error]    com.chuusai:shapeless _2.10, _2.10.2
[trace] Stack trace suppressed: run last client/*:update for the full output.
[error] (client/*:update) Conflicting cross-version suffixes in: com.chuusai:shapeless

In this case it is coming in via specs2 and another library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.