Comments (18)
Ok, submitted a ticket and pinged you there scala/scala3#16987.
I'm not sure what I wrote there make any sense, so it would be great if you chimed in.
from iron.
What is the definition of doSomething
?
Also, what does Concurrent[F].fromEither(...)
return?
from iron.
Here's completely self-contained example:
import cats.implicits.*
import cats.effect.Concurrent
import _root_.io.github.iltotore.iron.*
import _root_.io.github.iltotore.iron.constraint.string.*
type Name = String :| Alphanumeric
final case class Person(name: Name)
def test[F[_]: Concurrent](str: String): F[Person] =
Concurrent[F].fromEither(Either.catchNonFatal(str.refine[Alphanumeric])).map(n => Person(n))
What's interesting is that if I remove F[_]
and just map an Either
it compiles just fine.
from iron.
Concurrent[F].fromEither(...)
just lifts Either[Throwable, A]
into F[A]
.
from iron.
Another interesting observation - if I replace F[_]
with IO
- it works.
from iron.
This one fails:
def test[F[_]: Monad](str: String): F[Person] =
for {
_ <- Monad[F].unit
name = str.refine[Alphanumeric]
} yield Person(name)
This one doesn't:
def test[F[_]: Monad](str: String): F[Person] =
for {
_ <- Monad[F].unit
} yield Person(str.refine[Alphanumeric])
from iron.
What is the error for the last sample?
from iron.
In scala console:
-- Error: ----------------------------------------------------------------------
15 | } yield Person(name)
| ^^^^
|Cannot refine non full inlined input at compile-time.
|To test a constraint at runtime, use the `refined` extension method.
|
|Note: Due to a Scala limitation, already-refined types cannot be tested at compile-time (unless proven by an `Implication`).
|
|Inlined input: name
|----------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|This location contains code that was inlined from rs$line$1:15
----------------------------------------------------------------------------
1 error found
from iron.
From what I understand now, it seems that the type of name
is for some reasons reduced to String
in the for comprehension which would be (if I'm right) a bug in Scala's for desugaring. Can you try with flatMap/map?
from iron.
This one fails:
def test[F[_]: Monad](str: String): F[Person] =
Monad[F].unit
.map(_ => str.refine[Alphanumeric])
.map(name => Person(name))
This one doesn't:
def test[F[_]: Monad](str: String): F[Person] =
Monad[F].unit
.map { _ =>
val name = str.refine[Alphanumeric]
Person(name)
}
I agree with you that it's likely something in dotty, but I'd really appreciate an advice on where I can fill a bug as I don't have much knowledge of Iron (tried it for the first time today) nor dotty compile-time magic.
from iron.
Funny. Making F
contravariant solves the problem. This one works:
def test[F[-_]: Monad](str: String): F[Person] =
Monad[F].unit
.map(_ => str.refine[Alphanumeric])
.map(name => Person(name))
from iron.
Funny. Making F contravariant solves the problem.
As you said: it's funny 😅
What if you pass explicitly the generic types to map
like map[String :| Alphanumeric]
?
from iron.
Also this:
Either.catchNonFatal(str.refine[Alphanumeric])
Can be replaced by str.refineEither[Alphanumeric]
from iron.
'd really appreciate an advice on where I can fill a bug as I don't have much knowledge of Iron (tried it for the first time today) nor dotty compile-time magic.
For questions, you can ask in the Scala offcial Discord server. For Scala 3 issues, you should file to https://github.com/lampepfl/dotty
from iron.
Before fill in an issue for dotty, I just wanted to investigate the internals a bit (I know nothing about macro, compilers nor inlining).
The only place that can cause this compile-time error is this (grep'ed the codebase). And I find it very strange that something that should be called only on a constant is called on clearly a runtime value. So, are we sure it's non-Iron bug and has something to do with reducing inside F[_]
?
from iron.
It's not because the implicit conversion is triggered by Scala only if the types do not match. Since you already refined via refine
your type and assuming Person takes a String :| Alphanumeric
it will never be triggered if the types correspond. This means that Scala widen the type too much (aka to String
). I will do some tests once at home.
It might be useful to display the input type when the constraint is not evaluable at compile time. Noted for the next update.
from iron.
Update: this code works:
def test[F[_]: Monad](str: String): F[Person] =
Monad[F].unit
.map[String :| Alphanumeric](_ => str.refine[Alphanumeric])
.map(name => Person(name))
So it really looks like a Scala type inference issue.
from iron.
Closed since the Dotty issue got assigned to a milestone. Feel free to open a new one if you have any question or if the bug is finally also caused by Iron itself.
from iron.
Related Issues (20)
- Add Ciris documentation and entry in README
- Add documentation on RuntimeConstraint
- Compiler crash on v2.3.0: cannot resolve reference toRefinedTypeOps.type.Mirror HOT 8
- Add further documentation for Doobie module HOT 1
- Make zio-json derive work with opaque types HOT 3
- Documentation still refers to RefinedTypeOpsImpl
- Support first order types HOT 5
- Rename `.refine` into `.refineUnsafe` HOT 2
- Is Show[A] really needed to summon Meta[A :| C] instances for the doobie support HOT 2
- Use fewerBraces in Iron codebase HOT 2
- Create an instance of Int :| Positive from 0 without exceptions. HOT 6
- Add NonEmptyString type HOT 2
- Support iron types for avro4s schema HOT 2
- Spark/Gallia/... support?
- Better diagnostics for compile-time errors
- Change color of error message HOT 2
- deprecation warning does not show for `refine` HOT 3
- Better String support at compile-time HOT 1
- Use skunk 1.0.0-M.x instead of 0.6.x HOT 3
- Generating Avro4s.Schema fails HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from iron.