@LPTK I think this is equivalent to:
(x => x)(1)
All I can say without looking deeper into it is that it doesn’t seem impossible, maybe open an issue so we keep track of that ?
@lrytz PRs adding test cases are more than welcome!
@LPTK I think this is equivalent to:
(x => x)(1)
All I can say without looking deeper into it is that it doesn’t seem impossible, maybe open an issue so we keep track of that ?
@lrytz PRs adding test cases are more than welcome!
@smarter no it’s not. The following works well in all versions of Scala:
implicit class Helper[A](self: A) {
def |> [B] (rhs: A => B): B = rhs(self)
}
1 |> (x => x)
Ah indeed, can you rewrite it without the cats dependency to make things simpler to analyze ?
Here’s a bizarre implicit resolution problem that I once found:
trait Typeclass[T]
object Typeclass {
implicit def seqTC[C[X] <: Seq[X], T: Typeclass]: Typeclass[C[T]] = ???
implicit def setTC[C[X] <: Set[X], T: Typeclass]: Typeclass[C[T]] = ???
}
class Stuff[T]
object Stuff {
implicit val stuffTC: Typeclass[Stuff[_]] = ???
}
object Test {
implicitly[Typeclass[Stuff[_]]] // error!
}
The result is:
error: diverging implicit expansion for type Typeclass[Stuff[_]]
starting with method setTC in object Typeclass
implicitly[Typeclass[Stuff[_]]]
Workaround for this is to add redundant with Seq/Set[T]
to the result types of implicits:
implicit def seqTC[C[X] <: Seq[X], T: Typeclass]: Typeclass[C[T] with Seq[T]] = ???
implicit def setTC[C[X] <: Set[X], T: Typeclass]: Typeclass[C[T] with Set[T]] = ???
I maintain a project (https://chisel.eecs.berkeley.edu/) where our users commonly use anonymous classes as in the following pattern:
Implementing trait field with anonymous subclass:
abstract class Foo
trait Bar {
def foo: Foo
}
object Test extends App with Bar {
val foo = new Foo {
val x = 3
}
println(foo.x)
}
-Xsource:2.11
This is my main use case but there is a similar one:
Merely having a field that is an anonymous subclass:
abstract class Foo
object Test extends App {
val foo = new Foo {
val x = 3
}
println(foo.x)
}
The above examples can also be found on my Github repo: https://github.com/jackkoenig/scala-anon-class-type-inference
Those changes are intentional:
Foo { val x: Int }
in your example), these types are problematic since calling x
requires using Java runtime reflection.It’d be useful to know more about your usecases to think of alternative patterns that could be used for them.
It looks similar to issue#9487
When a type of an anonymous class is less specific that the definition of the class (AnyRef for example) the anonymous class methods become private.
Like @jackkoenig above, I’m involved in chisel. In attempting to see how much work porting the firrtl sub-project will be, I ran into an issue. It boils down to this:
trait A {
val a: Int = 0
}
trait B {
val b: Int = 1
}
object C {
def apply(b: B): Unit = b match {
case a: A => println(s"${a.a + a.b}")
}
}
This example typechecks in scala 2.12, but not dotty 0.13.0-RC1. Is this intended behavior that is considered good? The advice the compiler gives is ${a.a + b.b}
, which seems bad because it hides the fact that a
and b
are the same. I also tried case a: A | B =>
which I thought should work but is evidently wrong.
That one is an actual issue you can work around by doing case a: A & B => ...
, see https://github.com/lampepfl/dotty/issues/3208, if this is blocking you from porting code we can try to prioritize it.
Good to know, thanks for the issue link. Rather than blocking, I’d say slowing- there are lots of instances of this issue.
Can this restriction be lifted for final val
overrides (which are supposed to always narrow, under the Literal Singleton Types proposal, afaik)? I have multiple pieces of code that intentionally use override narrowing to either 1. compute String singletons 2. derive & recover type members from overrides of GADT member values, e.g.
private[example] trait HandlerBase {
type Target
def handlesTarget: TargetGroup.Aux[Target]
protected val target: TargetGroup
def process(t: Target): Unit
}
// derive type Target from `final val target`
trait Handler extends HandlerBase {
override type Target = target.T
override def handlesTarget: TargetGroup.Aux[target.T] = target
}
sealed trait TargetGroup { type T }
case object strTgt Textends TargetGroup { type T = String }
// usage
final class Handler1 extends Handler {
final val target = strTgt
def process(t: String): Unit = {}
}
That sounds reasonable and in fact it’s already how Dotty behaves!
A way to maintain the old meaning of
would be to rewrite it to:
object foo extends Foo { val x = 3 }
That would keep x
as a visible member of foo
.
One caveat here:
object foo extends Foo { val x = 3 }
// is eq to
lazy val foo = new Foo { val x = 3 }
//------------------------------------
object foo extends Foo { val x = 3 }
foo //this line produces warning ...
// is eq to
val foo = new Foo { val x = 3 }
if(true){
true: java.lang.Boolean
}else{
false
}
Scala 2.x can’t infer the correct type of this expression, and many other expressions where one branch is a subclass of AnyVal and the other is the java wrapper. Not sure how easy this would be to fix, since it has to do with implicit conversions.
This came up for real when I had to interact with Java I was doing something like this
public class User {
private Boolean isEnabled;
//getters setters, etc...
}
And in scala I was doing something like
val maybeNullPerson = Option(getUser())
val thatPersonEnabled = maybeNullPerson.map(_.isEnabled).getOrElse(false)
if(thatPersonEnabled) {
//...
Since the inferred type was Any
I had to do this
val thatPersonEnabled = maybeNullPerson.map(_.isEnabled).getOrElse[java.lang.Boolean](false)
I’m not convinced Scala should infer anything other than Any here. Which type would you consider “correct”?
Yeah, the current behavior might be the best, but the other option would be to automatically infer java.lang.Boolean
, since that’s the wrapper type for scala.Boolean
.
Why not scala.Boolean
in this case? This value is used in if
in your example. So, it’s unclear why complier should prefer Java’s one.
Why you think compiler should apply implicit conversion inside if
and at other usages of thatPersonEnabled
as boolean (inferring java.lang.Boolean
for thatPersonEnabled
) instead of applying implicit conversion at _.isEnabled
call (thus inferring scala.Boolean
for thatPersonEnabled
).
java.lang.Boolean can be null, but scala.Boolean cannot, so I would not want to convert.
On the other hand, Scala thinks that’s fine:
**Welcome to Scala 2.12.7 (OpenJDK 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.
(true: java.lang.Boolean).asInstanceOf[Boolean]
res0: Boolean = true
(null: java.lang.Boolean).asInstanceOf[Boolean]
res1: Boolean = false**