@@ -4,38 +4,48 @@ package progscala3.typesystem.bounds.list
44import scala .annotation .targetName
55import java .util .NoSuchElementException
66
7- sealed abstract class AbbrevList [+ A ]:
8-
9- def isEmpty : Boolean
10- def head : A
11- def tail : AbbrevList [A ]
12-
13- @ targetName(" prepend" )
14- def :: [B >: A ] (x : B ): AbbrevList [B ] = new :: (x, this )
15-
16- final def foreach (f : A => Unit ) =
17- var these = this
18- while ! these.isEmpty do
19- f(these.head)
20- these = these.tail
21-
22- // The empty AbbrevList.
23-
24- case object AbbrevNil extends AbbrevList [Nothing ]:
25- override def isEmpty = true
26-
27- def head : Nothing =
28- throw NoSuchElementException (" head of empty AbbrevList" )
29-
30- def tail : AbbrevList [Nothing ] =
31- throw NoSuchElementException (" tail of empty AbbrevList" )
32-
33- // A non-empty AbbrevList characterized by a head and a tail.
34-
35- @ targetName(" AbbrevListCons" )
36- final case class :: [B ](private var hd : B ,
37- private [list] var tl : AbbrevList [B ]) extends AbbrevList [B ]:
38-
39- override def isEmpty : Boolean = false
40- def head : B = hd
41- def tail : AbbrevList [B ] = tl
7+ /**
8+ * Scala 3.2 no longer allows top-level classes to have @targetName annotations.
9+ * From the error message printed by the compiler:
10+ * This restriction is due to the naming convention of Java classfiles, whose filenames
11+ * are based on the name of the class defined within. If @targetName were permitted
12+ * here, the name of the classfile would be based on the target name, and the compiler
13+ * could not associate that classfile with the Scala-visible defined name of the class.
14+ * One solution is to wrap the types in an object, as done here, which is not shown in the book.
15+ */
16+ object AbbrevListModule :
17+ sealed abstract class AbbrevList [+ A ]:
18+
19+ def isEmpty : Boolean
20+ def head : A
21+ def tail : AbbrevList [A ]
22+
23+ @ targetName(" prepend" )
24+ def :: [B >: A ] (x : B ): AbbrevList [B ] = new :: (x, this )
25+
26+ final def foreach (f : A => Unit ) =
27+ var these = this
28+ while ! these.isEmpty do
29+ f(these.head)
30+ these = these.tail
31+
32+ // The empty AbbrevList.
33+
34+ case object AbbrevNil extends AbbrevList [Nothing ]:
35+ override def isEmpty = true
36+
37+ def head : Nothing =
38+ throw NoSuchElementException (" head of empty AbbrevList" )
39+
40+ def tail : AbbrevList [Nothing ] =
41+ throw NoSuchElementException (" tail of empty AbbrevList" )
42+
43+ // A non-empty AbbrevList characterized by a head and a tail.
44+
45+ @ targetName(" AbbrevListCons" )
46+ final case class :: [B ](private var hd : B ,
47+ private [list] var tl : AbbrevList [B ]) extends AbbrevList [B ]:
48+
49+ override def isEmpty : Boolean = false
50+ def head : B = hd
51+ def tail : AbbrevList [B ] = tl
0 commit comments