Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Oleg Pyzhcov
@oleg-py
is it not working for you?
Christopher Davenport
@ChristopherDavenport
What is the pattern to raise it, as I can’t get it to work.
Oleg Pyzhcov
@oleg-py
implicit0(x) = stuffIWannaMakeImplicit or implicit0(x) <- stuffInFIWannaMakeImplicit
Christopher Davenport
@ChristopherDavenport
Yeah, thats a bunch of broken for me. :smile:
Oleg Pyzhcov
@oleg-py
can you provide an example of how it's broken?
Christopher Davenport
@ChristopherDavenport
[error] /Users/cdavenport/Documents/Scala/Examples/quickstart/src/main/scala/com/example/quickstart/Server.scala:19:16: recursive value helloWorldAlg needs type
[error]       implicit0(h1) = helloWorldAlg
[error]                ^
[error] /Users/cdavenport/Documents/Scala/Examples/quickstart/src/main/scala/com/example/quickstart/Server.scala:27:30: could not find implicit value for parameter H: com.example.quickstart.HelloWorldAlg[F]
[error]         Edge.helloWorldRoutes[F] <+>
[error]                              ^
[error] /Users/cdavenport/Documents/Scala/Examples/quickstart/src/main/scala/com/example/quickstart/Server.scala:17:14: type mismatch;
[error]  found   : h1.type (with underlying type Any)
[error]  required: AnyRef
[error]       client <- BlazeClientBuilder[F](global).stream
[error]              ^
[error] /Users/cdavenport/Documents/Scala/Examples/quickstart/src/main/scala/com/example/quickstart/Server.scala:37:22: type mismatch;
[error]  found   : Any
[error]  required: cats.data.Kleisli[F,org.http4s.Request[F],org.http4s.Response[F]]
[error]         .withHttpApp(finalHttpApp)
[error]                      ^
[error] four errors found
Will create an example repo here quickly. That was off my quickstart example for http4s where I raised implicitly with the plugin
Oleg Pyzhcov
@oleg-py
Thanks, I'll take a look in the next few days :blush:
Oleg Pyzhcov
@oleg-py
ty
Oleg Pyzhcov
@oleg-py
@ChristopherDavenport I opened a PR for your repository. New version published, obviously :smile:
Christopher Davenport
@ChristopherDavenport

Very cool. Do I misunderstand the stages in a flatMap one can do

myF.flatMap{ implicit myValue => withImplicit}

How is the plugin behaving differently than that behavior?

i.e. the need for explicit annotation, as I guarantee introduction with this will require me to explain how it works.
Oleg Pyzhcov
@oleg-py
Scala sometimes refuses to see implicit values if they are not given a type annotation - and this is going to become a strict requirement in Scala 3 IIRC. So you might have a value in the implicit scope, but without type they are not going to be picked during resolution. I believe (but I might be wrong) that implicit x => is special cased to work in that regard.

There's also the case with = bindings, as with something like

for {
x <- fa
jokeAlg = ???
...

you might get the desugaring of

fa.map(x =>
  val jokeAlg = ???
  // do something which requires implicit jokeAlg
   (x, jokeAlg)
).flatMap { case (x, jokeAlg) => ... }

The plugin ensures that your implicit values will be visible in both map and flatMap branches, which is rather tricky, but it works in top-down fashion as with normal method calls.

Christopher Davenport
@ChristopherDavenport
That sounds great. Thank you for the clarity.
Christopher Davenport
@ChristopherDavenport
Its a little verbose. But it makes the final function so much cleaner looking.
Oleg Pyzhcov
@oleg-py
I know. You can rely on the inference where you know your type is a subtype of AnyRef by using singleton type, i.e. implicit val a$1: a.type = a- which I tried. Unfortunately, it's possible to either fail inference (resulting in confusing "recursive value needs type" or "found a.type required AnyRef" in generic contexts), so I decided it's worth going for a verboser, but more stable alternative.
Christopher Davenport
@ChristopherDavenport
Totally fair. Its actually quite nice the more I look at it. Its just going to take a little adjustment.
Oleg Pyzhcov
@oleg-py
Thank you a lot for being an early tester :)
Christopher Davenport
@ChristopherDavenport
My pleasure, I’m going to introduce it around at $WORK and see how it goes.
Fabio has expressed concerns over the introduction of a new keyword in the http4s channel. However I don’t share that concern very much.
Oleg Pyzhcov
@oleg-py
I'd love to be able to just reuse implicit, but that's what plugins can't do yet. I hope it eventually becomes a SIP in Scala 3
besides, it's always possible to turn the feature off :smirk:
Christopher Davenport
@ChristopherDavenport
@oleg-py Bug incoming. Your expansion of for-comprehension breaks with the new scala 2.12.7 unused checks.
Philippe Derome
@phderome
I just tried it out, like it, and am sharing basic observations. I am using maven and was generating scaladocs and the attach-scaladocs within maven-scala-plugin was failing after passing all compilation and tests under some circumstances. I removed that maven noise as I don't need to generate docs (proprietary code). Some tuple constructs as (a, b) = pair in a monadic for no longer compiled so I had to fix it, which was very pleasant (sincerely). And some unnecessary constructs to validate with scalatest matchers inside the monadic for (using _ = somenonunitexpressionthatisamatcher) were failing unless I turned off a compiler plugin option so I moved that test in the yield part and everything was fine. Congrats on a good project.
Philipp Martini
@maphi

Hey, it looks like wartremover 2.3.7 and better-monadic-for 0.3.0-M4 get in their way:

 for {
  ...
  (a,b) = foo
} yield ()

this reports error: [wartremover:NonUnitStatements] Statements must return Unit
any suggestions? is there an order to specify for scalac plugins?

Oleg Pyzhcov
@oleg-py
@maphi your example isn't very specific (and for ... yield is non-Unit itself). You can try disabling optimizations (-P:bm4:no-map-id:n and/or -P:bm4:no-tupling:n)
Philipp Martini
@maphi
@oleg-py thx that worked!
the line causing the error was the (a,b) = foo
Yuriy Badalyantc
@LMnet

Hi everybody! I had a problem with the cats.effect.Resource with the next code:

for {
  mongoClient <- Resource.make(acquire)(release)
  bookletsCollection <- Resource.liftF(getCollection(mongoClient))
  storage <- Resource.pure(createStorage(bookletsCollection))
} yield storage

And the error is:

[error] /.../MongoDbBookletsStorage.scala:45:31: value map is not a member of cats.effect.Resource[F,ru.dgis.market.booklets.storage.BookletsStorage[F]]
[error]       storage <- Resource.pure(createStorage(bookletsCollection))
[error]

I added better-monadic-for in my project to solve this issue. I checked in the sbt that compiler plugin was added. But I'm still facing the same issue. What am I doing wrong?

Manual rewriting solves the problem:
Resource.make(acquire)(release).flatMap { mongoClient =>
  Resource.liftF(getCollection(mongoClient)).flatMap { bookletsCollection =>
    Resource.pure(createStorage(bookletsCollection))
  }
}
But what better-monadic-for didn't do that for me?
Christopher Davenport
@ChristopherDavenport
You need import cats.implicits._ to have map on resource.
It is slated to be fixed in the next release of cats effect.
Yuriy Badalyantc
@LMnet
@ChristopherDavenport with this import a have another error:
[error] /.../MongoDbBookletsStorage.scala:42:31: diverging implicit expansion for type cats.kernel.Order[A]
[error] starting with method catsKernelStdOrderForVector in trait VectorInstances
[error]       storage <- Resource.pure(createStorage(bookletsCollection))
[error]
Oleg Pyzhcov
@oleg-py
@LMnet just use yield createStorage(...) or write pure with all types
Yuriy Badalyantc
@LMnet
@oleg-py tried yield createStorage:
[error] /.../MongoDbBookletsStorage.scala:44:43: value map is not a member of cats.effect.Resource[F,org.mongodb.scala.MongoCollection[org.mongodb.scala.bson.collection.immutable.Document]]
[error]       bookletsCollection <- Resource.liftF(getCollection(mongoClient))
[error]
Oleg Pyzhcov
@oleg-py
With import cats.implicits._
Yuriy Badalyantc
@LMnet
With imported cats.implicits._:
[error] /.../MongoDbBookletsStorage.scala:46:26: polymorphic expression cannot be instantiated to expected type;
[error]  found   : [F(in method pure)[_]]cats.effect.Resource[F(in method pure),ru.dgis.market.booklets.storage.BookletsStorage[F(in method apply)]]
[error]  required: ru.dgis.market.booklets.storage.BookletsStorage[F(in method apply)]
[error]     } yield Resource.pure(createStorage(bookletsCollection))
[error]
Oleg Pyzhcov
@oleg-py
With import cats.implicits._ and without Resource.pure
Yuriy Badalyantc
@LMnet
Now it works! Thanks
Oleg Pyzhcov
@oleg-py
Better-monadic-for doesn't remove the need for having a map, btw:
oleg-py/better-monadic-for#15
it can just sometimes optimize the call away, but it needs to typecheck first
Yuriy Badalyantc
@LMnet
It looks like I misunderstood the docs. I thought that bm4 could completely remove map.
Thread in the issue is helpful
Oleg Pyzhcov
@oleg-py
It would remove map, but only if it can prove it's safe to do. And to prove that, it needs to be done after typer
Jakub Kozłowski
@kubukoz
image.png
latest nightlies of IDEA seem to work with implicit0 :P
thanks to the work of @sugakandrey
Christopher Davenport
@ChristopherDavenport
:100: