methode map in class cats.data.Nested not recognized - scala

I have a problem when folowing the scala cats library tutorial, the map method applied to the Nested class is highlighted with red, and the compiler doesn't recognize it.
here is my main class code :
import cats._
import cats.data._
import cats.implicits._
import cats.syntax.functor._
import cats.Functor
import cats.instances.list._
import cats.instances.option._
object Main extends App{
val list = List(Some(1), Some(2), None, Some(4))
val nested: Nested[List, Option, Int] = Nested(list)
//here is the problem
nested.map(_ + 1)
}
here is my build.sbt file
name := "dailySBT3"
version := "0.1"
scalaVersion := "2.12.5"
scalacOptions += "-Ypartial-unification"
libraryDependencies += "org.typelevel" %% "cats-core" % "1.1.0"

The problem is you are importing the instances and syntax twice. The following works for me with no problems:
import cats._
import cats.data._
import cats.implicits._
object Main extends App{
val list = List(Some(1), Some(2), None, Some(4))
val nested: Nested[List, Option, Int] = Nested(list)
nested.map(_ + 1)
}
You could also do the same thing as above but get rid of the cats.implicits._ import instead.
When in doubt, check out the cats import guide.

Related

How to convert JSON to scala shapeless.hlist?

I got json like {"name":"susan","age":25},and a hint to json keyset like "name:String,age:Int",how to create a HList from that json?
Based on the code you added and then deleted, it seems, having a runtime-string hint "name:String,age:Int" and runtime-string json {"name":"susan","age":25}, you want to get an HList with runtime reflection. You can do this as follows
import shapeless.HList
import scala.reflect.runtime
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val tb = runtime.currentMirror.mkToolBox()
val jsonStr = """{"name":"susan","age":25}"""
val hint = "name:String,age:Int"
val classType = tb.define(tb.parse(s"case class Test($hint)").asInstanceOf[ImplDef]).asClass.toType
val hlist = tb.eval(q"""
import io.circe.generic.auto._
import io.circe.parser.decode
val classInstance = decode[$classType]($jsonStr)
import shapeless.Generic
Generic[$classType].to(classInstance.toOption.get)
""").asInstanceOf[HList]
println(hlist) // susan :: 25 :: HNil
Please notice that you do everything at runtime so you'll have no access to type String :: Int :: HNil at compile time and hlist has static type just HList (not String :: Int :: HNil) and HList is actually not better than just List[Any].
build.sbt
libraryDependencies ++= Seq(
scalaOrganization.value % "scala-reflect" % scalaVersion.value,
scalaOrganization.value % "scala-compiler" % scalaVersion.value,
"com.chuusai" %% "shapeless" % "2.4.0-M1",
"io.circe" %% "circe-core" % "0.13.0",
"io.circe" %% "circe-parser" % "0.13.0",
"io.circe" %% "circe-generic" % "0.13.0"
)
Actually, I guess we do someting strange. We use highly type-level libraries (shapeless, circe) aimed to static type safety and then run them at runtime with reflection ignoring type safety and getting actually List[Any] (HList).
I guess that if List[Any] (list of field values) is enough for you then you just need to use a more runtime library. For example, with json4s
import org.json4s.{JInt, JObject, JString, JValue}
import org.json4s.jackson.JsonMethods._
val jsonStr: String = """{"name":"susan","age":25}"""
val json: JValue = parse(jsonStr) //JObject(List((name,JString(susan)), (age,JInt(25))))
val l: List[JValue] = json.asInstanceOf[JObject].obj.map(_._2) //List(JString(susan), JInt(25))
val res: List[Any] = l.map {
case JString(s) => s
case JInt(n) => n
} //List(susan, 25)
build.sbt
libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.6.9"
Actually the same can be done with Circe, just with parse instead of decode[A]
import io.circe.{Json, JsonNumber}
import io.circe.parser.parse
val jsonStr: String = """{"name":"susan","age":25}"""
val json: Json = parse(jsonStr).toOption.get //{"name":"susan","age":25}
val l: List[Json] = json.asObject.get.values.toList //List("susan", 25)
val res: List[Any] = l.map(_.fold[Any](null, null, (_: JsonNumber).toInt.get, identity[String], null, null)) //List(susan, 25)
If you need an instance of case class or a tuple rather than HList replace
tb.eval(q"""
import io.circe.generic.auto._
import io.circe.parser.decode
val classInstance = decode[$classType]($jsonStr)
import shapeless.Generic
Generic[$classType].to(classInstance.toOption.get)
""").asInstanceOf[HList] // susan :: 25 :: HNil
with
tb.eval(q"""
import io.circe.generic.auto._
import io.circe.parser.decode
decode[$classType]($json).toOption.get
""").asInstanceOf[Product] //Test(susan,25)
or
tb.eval(q"""
import io.circe.generic.auto._
import io.circe.parser.decode
val classInstance = decode[$classType]($json)
import shapeless.Generic
Generic[$classType].to(classInstance.toOption.get).tupled
""").asInstanceOf[Product] //(susan,25)
correspondingly.

when I upgraded my ReactiveMongo library dependencies from 0.11.0.play24 to 0.11.14-play24 it throws me error

I'am upgrading the play from 2.4.3 to 2.5.2 in the process I was able to upgrade the play but when I upgraded the reactive mongo library dependency from 0.11.0.play24 to 0.11.14-play24 it was throwing following errors
found : (String, play.api.libs.json.JsValue)
[error] required: reactivemongo.bson.Producer[reactivemongo.bson.BSONElement]
[error] (which expands to) reactivemongo.bson.Producer[(String, reactivemongo.bson.BSONValue)]
[error] Error occurred in an application involving default arguments.
[error] claimsCollection.update(BSONDocument("id" -> claimId), BSONDocument("$set" -> BSONDocument("status"-> "Approved" , "updationDate" -> Json.toJson(ZonedDateTime.now()))))
[error]
The code I have written like this
import com.greenroom6.auth.models.claims.Claims
import javax.inject.Inject
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
import scala.concurrent.ExecutionContext
import com.greenroom6.auth.util.UniqueIdGenerator
import reactivemongo.bson.BSONDocument
import play.api.libs.json.{Json,JsObject}
import play.modules.reactivemongo.json._
import scala.concurrent.Future
import reactivemongo.api.commands.WriteResult
import reactivemongo.api.ReadPreference
import java.time.ZonedDateTime
import play.modules.reactivemongo.json._,ImplicitBSONHandlers._
import reactivemongo.bson._
import play.modules.reactivemongo.ReactiveMongoComponents
class ClaimsDaoImpl #Inject()(reactivemongo : ReactiveMongoApi) extends ClaimsDao {
protected def claimsCollection = reactivemongo.db.collection[JSONCollection]("claims")
def claimProfile(claim:Claims)(implicit ec :ExecutionContext): Future[WriteResult] = {
val claimTosave = claim.copy(id = Some(UniqueIdGenerator.generate), status = "Pending" )
claimsCollection.save(claimTosave)
}
def approveClaim(claimId:String)(implicit ec :ExecutionContext): Future[WriteResult] = {
claimsCollection.update(BSONDocument("id" -> claimId), BSONDocument("$set" -> BSONDocument("status"-> "Approved" , "updationDate" -> Json.toJson(ZonedDateTime.now()))))
}
}
What should I require to do to resolve the issue?
I think you have the wrong dependency. According to their Github Page: ReactiveMongo/Play-ReactiveMongo
val reactiveMongoVer = "0.11.14"
// only for Play 2.5.x
libraryDependencies ++= Seq(
"org.reactivemongo" %% "play2-reactivemongo" % reactiveMongoVer
)
Instead it seems you use this:
// only for Play 2.4.x
libraryDependencies ++= Seq(
"org.reactivemongo" %% "play2-reactivemongo" % s"$reactiveMongoVer-play24"
)

missing Cats Functor[Future] instance

I am trying to use OptionT to combine methods returning Future[Option[T]] in a for-comprehension.
import cats.data._
import cats.implicits._
import cats.instances.future._
for {
data <- OptionT(repo.getData(id))
...
}
The compiler error I am getting:
could not find implicit value for parameter F cats.Functor[scala.concurrent.Future]
This recent example suggests that this is (was?) possible.
so do the docs in the pull request for adding OptionT
and the cats Functor docs
What am I missing here?
Thank you
By importing cats.implicits._ you are actually already importing cats.syntax.AllSyntax and cats.instances.AllInstances
Try using just those imports:
import cats.data._
import cats.implicits._
or (according to your needs):
import cats.data._
import cats.instances.future._
or more specifically:
import cats.data._
import cats.instances.future.catsStdInstancesForFuture
you may also need:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
Note: of course you have to implicitly provide an actual ExecutionContext in a production environment.
Following imports work for me (also mentioned in approved answer),
import cats.data.OptionT
import cats.instances.future._ // or import cats.implicits._
// as implicits include FutureInstances
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
Also, the important thing was the dependencies as I was using org.typelevel:cats:0.9.0 along with cats-core-1.1.0 which was causing Symbol 'type cats.kernel.instances.EqInstances' is missing from the classpath.
Had to remove older cats-0.9.0 and use latest cats-core and cats-kernel.
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % "1.1.0",
"org.typelevel" %% "cats-kernel" % "1.2.0",
"org.scalatest" %% "scalatest" % "3.0.4" % Test
)
Seems like causes of this issue can be various; I just ran into this because I had two implicit ExecutionContexts available in scope, so cats was unable to select one to provide the Functor[Future]:
import scala.concurrent.ExecutionContext.Implicits.global
// ^ first implicit ExecutionContext
class MyClass {
def myMethod(e: EitherT[Future, _, _])(implicit ec: ExecutionContext) {
// Second implicit ExecutionContext
e.flatMap(...) // <- Functor unavailable
}
}
In my case I was able to resolve the issue by simply not passing ec into myMethod, though removing the global execution context would have also worked.
Had the same problem. cats actually has the instance.
The real issue is just the implicit ExecutionContext missing which you could just do the following
import scala.concurrent.ExecutionContext.Implicits.global
I realised this when I was trying to provide an instance for it.
implicit val ev: Functor[Future] = new Functor[Future] {
override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f)
}
It's at this point the compiler will say the missing the implicit ExecutionContext

Could not access type Unmarshaller in value akka.http.javadsl.unmarshalling

I am trying to write a simple Http client using Akka Http Client API. Towards this I have written the following code
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import scala.concurrent.duration._
import scala.concurrent.{Await}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._
final case class Post(postId: Int, id: Int, name: String, email: String, body: String)
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val postFormat = jsonFormat5(Post.apply)
}
class AkkaHttpClient extends App with Directives with JsonSupport {
implicit val system = ActorSystem("my-Actor")
implicit val actorMaterializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val httpClient = Http().outgoingConnection(host="http://jsonplaceholder.typicode.com/")
val flow = Source.single(HttpRequest(uri = Uri("/comments/1")))
.via(httpClient)
.mapAsync(1)(r => Unmarshal(r.entity).to[Post])
.runWith(Sink.head)
val results = Await.result(flow, 15 seconds)
println(results)
}
My build.sbt file looks like
name := "Akka-Http-Client"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http-experimental" % "2.4.9-RC1",
"com.typesafe.akka" %% "akka-http-spray-json-experimental" % "2.4.9-RC1"
)
When I try to compile my code I get these errors
Error:scalac: missing or invalid dependency detected while loading class file 'Unmarshaller.class'.
Could not access type Unmarshaller in value akka.http.javadsl.unmarshalling,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'Unmarshaller.class' was compiled against an incompatible version of akka.http.javadsl.unmarshalling.
I am having the same problem on 2.4.9-RC1, falling back to 2.4.8 solves the problem.
OR you could use this workaround described here: https://github.com/akka/akka/issues/21105

Set a limit to scala.rx timer

Here is an example using Timer from scala.rx:
package tutorial.webapp
import akka.actor.ActorSystem
import rx.core.{Rx, Var}
import rx._
import rx.ops._
import scala.concurrent.Promise
import scala.concurrent.duration._
import scala.scalajs.js.JSApp
import scala.scalajs.js.annotation.JSExport
import scala.concurrent.ExecutionContext.Implicits.global
/**
* Created by IDEA on 29/10/15.
*/
object RxAddtionalOps extends JSApp {
#JSExport
override def main(): Unit = {
timer1
}
def timer1: Unit = {
implicit val scheduler = new DomScheduler
val t = Timer(100 millis)
var count = 0
val o = Obs(t){
count = count + 1
println(count)
}
}
}
When you run runMain tutorial.webapp.RxAddtionalOps from sbt, the console will be indefinitely blocked. Can I set a limit to the timer? For example, to make it stop emitting events in 2 minutes.
First of all, Scala is a language for express common programming patterns in a concise, elegant, and type-safe way. So keep your work tidy!
Therefore
import akka.actor.ActorSystem
import rx.core.{Rx, Var}
import rx._
import scala.concurrent.Promise
is a lot of unnecessary noise. And if the target is a JavaScript platform, the Actor system is not available yet, maybe over couple of years.
Why should you fire runMain tutorial.webapp.RxAddtionalOps in sbt, while a simple run command will do?
I used the Timer.kill() method to terminate the execution after a limited time:
package tutorial.webapp
import rx.Obs
import rx.ops.{DomScheduler, Timer}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.language.postfixOps
import scala.scalajs.js.JSApp
object RxAddtionalOps extends JSApp {
val executionStart = scala.compat.Platform.currentTime
def main(): Unit = {
timer1()
}
def timer1() = {
implicit val scheduler = new DomScheduler
val t = Timer(100 millis)
var count = 0
Obs(t) {
count += 1
println(count)
if (count >= 19) {
t.kill()
println(s"Successfully completed without errors. [within ${
scala.compat.Platform.currentTime - executionStart
} ms]")
}
}
}
}
Since it is actually a headless phantom or rhino environment (depending on your build.sbt config) there can be no user initiated interrupt processed.
For completeness here the build.sbt file:
name := "RxAddtionalOps"
version := "1.0"
scalaVersion := "2.11.7"
enablePlugins(ScalaJSPlugin)
scalacOptions ++= Seq("-unchecked", "-deprecation","-feature")
libraryDependencies ++= Seq(
"com.lihaoyi" %%% "scalarx" % "0.2.8",
"org.scala-js" %% "scalajs-library" % "0.6.5"
)