Shapeless example with map won't compile (scala) - scala

I'm trying to map over an HList in shapeless. The following example is derived from here:
import shapeless._
import poly._
object Main {
def main(args: Array[String]) = {
object choose extends (Set ~> Option) {
def apply[T](s : Set[T]) = s.headOption
}
val sets = Set(1) :: Set("foo") :: HNil
val opts = sets map choose // map selects cases of choose for each HList element
}
}
Unfortunately I am unable to compile the example. The compiler says "value map is not a member of HCons[scala.collection.immutable.Set[Int],HCons[scala.collection.immutable.Set[String],HNil]]". I suspect there is a missing import of an implicit that defines the map operation on HLists, but I don't know what that import should be. I'm using sbt with the following build.sbt file:
name := "scala-polymorphism-experiments"
version := "0.1.0"
scalaVersion := "2.10.3"
resolvers ++= Seq(
"Sonatype OSS Releases" at "http://oss.sonatype.org/content/repositories/releases/",
"Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
)
libraryDependencies ++= Seq("org.scalatest" % "scalatest_2.10" % "2.0" % "test",
"com.chuusai" % "shapeless" % "2.0.0-SNAPSHOT" cross CrossVersion.full changing())
I also have this problem if I use the M1 release of 2.0.0. What should I change to make this example compile and run?

The problem was never determined. The solution was to comment out all code in all other scala files in the project, recompile, then uncomment and compile again. No doubt an
sbt clean
would have done just as well.

Related

Use sbt settingKey in function call

We have a build.sbt file like this, which is working fine:
name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"
def aws(module: String): ModuleID = "com.amazonaws" % module % "1.11.250"
lazy val Core = project
.settings(
libraryDependencies ++= Seq(
aws("aws-java-sdk-s3"),
aws("aws-java-sdk-dynamodb"),
)
)
Basically, the project has a few AWS SDK library dependencies and we want to avoid typing the groupID (e.g. "com.amazonaws") and the revision (e.g. "1.11.250") multiple times and that's why we have this line:
def aws(module: String): ModuleID = "com.amazonaws" % module % "1.11.250"
However, since we have many repos like this and we want to move this definition to a custom sbt-plugin. To begin with, we try this:
name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"
val awsVersion = settingKey[String]("The version of aws SDK used for building.") // line 5
def aws(module: String): ModuleID = "com.amazonaws" % module % awsVersion.value // line 6
awsVersion := "1.11.250"
lazy val Core = project
.settings(
libraryDependencies ++= Seq(
aws("aws-java-sdk-s3"),
aws("aws-java-sdk-dynamodb"),
)
)
However, line 6 is producing an error:
error: value can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting.
The idea is that we'll move line 5 and 6 above to our plugin eventually so that we can use it like this:
name := "Foo"
version := "0.1"
scalaVersion := "2.12.8"
awsVersion := "1.11.250"
lazy val Core = project
.settings(
libraryDependencies ++= Seq(
aws("aws-java-sdk-s3"),
aws("aws-java-sdk-dynamodb"),
)
)
Any solution or work around for the error above?
We've also tried this:
def aws(module: String, version: String): ModuleID = "com.amazonaws" % module % version
... which is then used like this:
awsVersion := "1.11.250"
lazy val Core = project
.settings(
libraryDependencies ++= Seq(
aws("aws-java-sdk-s3", awsVersion.value),
aws("aws-java-sdk-dynamodb", awsVersion.value),
)
)
That works fine though a bit annoying to use and it defeats the purpose of using a settingKey to begin with.
You cannot use setting or task values in locally defined methods like aws. The values can be used only within other setting or task definitions, ie the error message such as :=, +=, ++=, Def.task, or Def.setting.
This is what you could do.
Create AutoPlugin in project folder.
import sbt.{AutoPlugin, Def, ModuleID, settingKey}
import sbt.PluginTrigger.AllRequirements
import sbt._
object AwsPlugin extends AutoPlugin {
override def trigger = AllRequirements
type GetAWS = String => ModuleID
object autoImport {
val awsVersion =
settingKey[String]("The version of aws SDK used for building.")
val awsLibrary = settingKey[GetAWS]("Builds given AWS library")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] = Seq(
awsLibrary := { id =>
"com.amazonaws" % id % awsVersion.value
}
)
}
Use it in this way in build.sbt
awsVersion in ThisBuild := "1.11.250"
lazy val Core = project
.settings(
libraryDependencies ++= Seq(
awsLibrary.value("aws-java-sdk-s3"),
awsLibrary.value("aws-java-sdk-dynamodb"),
)
)

SBT test:compile is not satisfied by libraryDependencies in Test

I have the snippet of test case below under src/test/scala:
package example.module
import utest._
object ModuleSpec extends TestSuite { ... }
... which compiles just fine with this snippet of build.sbt below:
val testDependencies: Seq[ModuleID] =
Seq(
"com.lihaoyi" %% "utest" % "0.6.5" % "test",
)
def testSettings: Seq[Setting[_]] =
Seq(
libraryDependencies ++= testDependencies)
lazy val root =
(project in file("."))
.aggregate(subproject)
lazy val subproject =
(project in file("subproject"))
.settings(testSettings: _*)
My question is:
Why the test code does not compile anymore if I add Test axis to libraryDependencies, like shown below?
def testSettings: Seq[Setting[_]] =
Seq(
libraryDependencies in Test ++= testDependencies)
In more detail:
The line containing import utest._ fails to compile, meaning that the dependency which is now declared as part of libraryDependencies in Test was ignored.
Argumentation:
Since I'm compiling a class under src/main/test, I would expect that libraryDependencies in Test would be the necessary and the sufficient piece of information in this case. In order words: I would not expect that a wider scope would be needed.

error: not found: object play

Actually learning how to code with scala, I need some help on this:
import play.api.libs.json._
case class Alert(email: String, query: String)
{
def main(args: Array[String]): Unit = { println("Hello from main of class")}
}
I've got an error message :
Alert.scala:2: error: not found: object play
import play.api.libs.json._
One error found
I don't know where the problem come, I updated IntelliJ, and even added the missing library Dependencies in my build.sbt
name := """alert"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
jdbc,cache,ws,
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test,
"org.tpolecat" %% "doobie-core" % "0.4.1",)
I'm quite sure they explained it very well in this related question:
object play not found in scala application

How to add 'testListener' to custom test reporter in SBT

I'm having difficulty implementing a custom test reporter in Scala using SBT.
I have a basic SBT project set up with this build.sbt file:
name := "Test Framework"
version := "0.1"
scalaVersion := "2.11.7"
scalacOptions += "-deprecation"
scalacOptions += "-feature"
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.4" % "test"
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.4" % "test"
testFrameworks += new TestFramework("custom.framework.MyTest")
testListeners += new MyTest()
My MyTest.scala class is located in the projectsfolder under projects/custom/framework/MyTest.scala and looks like this:
import sbt.TestsListener._
import sbt.TestReportListener._
class MyTest extends TestReportListener {
def doInit(): Unit = {
println("Starting Test")
}
def testEvent(event: TestEvent): Unit = {
println(event.result.get)
}
def startGroup(name: String): Unit = {
println("Group Started")
}
}
The documentation here is sparse, and i'm obviously missing something. It states that i need to
Specify the test reporters you want to use by overriding the testListeners setting in your project definition. Where customTestListener is of type sbt.TestReportListener.
This should be possible by doing testListeners += customTestListener.
Since my class MyTest extends TestReportListener i thought i could just do testListeners += custom.framework.MyTest or testListeners += new custom.framework.MyTest, but this clearly is not the case.
I'm running sbt test to execute the tests, and the output is
error: not found: value custom
testListeners += new custom.framework.MyTest
I'm not sure how this is supposed to work.
Does anyone know how this is done correctly?
I did not figure out why stating the package did not work, but moving the MyTest.scala file out to the project directory, and removing the custom.frameworkpackage made it work.

Macros annotation not working in IntelliJ14

I am having trouble using Scala Macros. It keeps on telling me to
enable macro paradise to expand macro annotations
from the #compileTimeOnly message I wrote. I followed all the instructions from Macro annotation documentation and the SBT example.
IDE: IntelliJ 14.1
Scala version: 2.11.7
Build.scala under the Project folder:
import sbt._
import sbt.Keys._
object Build extends Build {
val paradiseVersion = "2.1.0-M5"
lazy val sm = Project(id = "server-modules", base = file(".")).settings(
version := "1.0",
logLevel := Level.Warn,
scalacOptions ++= Seq(),
scalaVersion := "2.11.7",
crossScalaVersions := Seq("2.10.2", "2.10.3", "2.10.4", "2.10.5", "2.11.0", "2.11.1", "2.11.2", "2.11.3", "2.11.4", "2.11.5", "2.11.6", "2.11.7"),
resolvers += Resolver.sonatypeRepo("snapshots"),
resolvers += Resolver.sonatypeRepo("releases"),
addCompilerPlugin("org.scalamacros" % "paradise" % paradiseVersion cross CrossVersion.full),
libraryDependencies <+= (scalaVersion)("org.scala-lang" % "scala-reflect" % _),
)
}
Code:
#compileTimeOnly("enable macro paradise to expand macro annotations")
class dmCompile extends StaticAnnotation{
def macroTransform(annottees: Any*): Any = macro DMCompile.impl
}
object DMCompile {
def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
Log.info("Work work work!")
c.Expr(q"""var x = y""")
}
}
#dmCompile class Test{}
What exactly am I missing?
This took me the entire day, but I got it working.
Simply disregard the SBT settings for macros paradise and manually add it in the Preference -> Scala Compiler
That's it!
For me a solution was to change Incrementality type from IDEA to SBT in the Settings. This allows to use native SBT's build engine instead of IDEA's one.