Why the following is not allowed? (2.12):
type Foo <: {def foo(): Unit}
type Bar <: {def bar(): Unit} with Foo
Looks natural to me, Bar
should have both foo()
and bar()
.
Why the following is not allowed? (2.12):
type Foo <: {def foo(): Unit}
type Bar <: {def bar(): Unit} with Foo
Looks natural to me, Bar
should have both foo()
and bar()
.
type Foo <: {def foo(): Unit}
is type Foo <: AnyRef{def foo(): Unit}
.
So while type Bar <: {def bar(): Unit} with Foo
is not parsable, with AnyRef
and different order it works
type Foo <: {def foo(): Unit}
type Bar <: Foo with AnyRef{def bar(): Unit}
val b: Bar = ???
b.foo()
b.bar()
Also with brackets (and direct order) it works
type Foo <: {def foo(): Unit}
type Bar <: ({def bar(): Unit}) with Foo
val b: Bar = ???
b.foo()
b.bar()
Actually type Bar <: {def bar(): Unit} with Foo
is against the spec while type Bar <: ({def bar(): Unit}) with Foo
satisfies the spec because {def bar(): Unit}
is not a SimpleType
but ({def bar(): Unit})
is a SimpleType
.
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
| Refinement
AnnotType ::= SimpleType {Annotation}
SimpleType ::= ............
| ‘(’ Types ‘)’
Types ::= Type {‘,’ Type}
Type ::= ...........
| CompoundType
| ...........
https://scala-lang.org/files/archive/spec/2.13/03-types.html#compound-types
Seems to work with parenthesis
scala> type Foo <: {def foo(): Unit}
| type Bar <: ({def bar(): Unit}) with Foo
type Foo
type Bar
type Foo <: {def foo(): Unit}
is type Foo <: AnyRef{def foo(): Unit}
.
So while type Bar <: {def bar(): Unit} with Foo
is not parsable, with AnyRef
and different order it works
type Foo <: {def foo(): Unit}
type Bar <: Foo with AnyRef{def bar(): Unit}
val b: Bar = ???
b.foo()
b.bar()
Also with brackets (and direct order) it works
type Foo <: {def foo(): Unit}
type Bar <: ({def bar(): Unit}) with Foo
val b: Bar = ???
b.foo()
b.bar()
Actually type Bar <: {def bar(): Unit} with Foo
is against the spec while type Bar <: ({def bar(): Unit}) with Foo
satisfies the spec because {def bar(): Unit}
is not a SimpleType
but ({def bar(): Unit})
is a SimpleType
.
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
| Refinement
AnnotType ::= SimpleType {Annotation}
SimpleType ::= ............
| ‘(’ Types ‘)’
Types ::= Type {‘,’ Type}
Type ::= ...........
| CompoundType
| ...........
https://scala-lang.org/files/archive/spec/2.13/03-types.html#compound-types
It's not allowed by the spec, which calls the { ...}
part a refinement which may both have a with clause. The other way around it's fine though.
That's somewhat tautological of course as it doesn't say why it's not allowed by the spec. It appears there is no deep understanding here, just that that's not a way you're allowed to write a type. You should be able to express the same intent in another way.
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] | Refinement
. Here {def bar(): Unit}
and Foo
are AnnotType
s, Refinement
is empty. –
Meadowlark AnnotType
is SimpleType {Annotation}
but {def bar(): Unit}
is not a SimpleType
–
Huckaby {def bar(): Unit}
is not a SimpleType
but ({def bar(): Unit})
is a SimpleType
. –
Meadowlark SimpleType ::= SimpleType TypeArgs | SimpleType ‘#’ id | StableId | Path ‘.’ ‘type’ | Literal | ‘(’ Types ‘)’
. Important is the last part, if you surround Types
with brackets then you get a SimpleType
. Types ::= Type {‘,’ Type}
, so one Type
is also Types
. {def bar(): Unit}
is a Type
(actually a CompoundType
consisting of single Refinement
), so ({def bar(): Unit})
is a SimpleType
. –
Meadowlark © 2022 - 2024 — McMap. All rights reserved.
<:
is not extending (inheriatance) but subtyping. cmi.ac.in/~madhavan/courses/pl2009/lecturenotes/lecture-notes/… – Meadowlark