[{"data":1,"prerenderedAt":3985},["ShallowReactive",2],{"page-\u002Fscala\u002F08-type-system":3},{"id":4,"title":5,"body":6,"description":28,"extension":3976,"meta":3977,"navigation":46,"path":3978,"seo":3979,"stem":3983,"__hash__":3984},"content\u002Fscala\u002F08-type-system.md","[object Object]",{"type":7,"value":8,"toc":3960},"minimark",[9,14,19,340,344,539,551,1018,1022,1352,1359,2143,2147,2766,2770,3041,3045,3394,3398,3721,3725,3739,3771,3783,3792,3796,3810,3834,3842,3848,3852,3874,3956],[10,11,13],"h1",{"id":12},"_08-type-system-variance-bounds-givens-phantom-types","08 — Type System: Variance, Bounds, Givens & Phantom Types",[15,16,18],"h2",{"id":17},"variance-the-subtyping-of-generics","Variance — The Subtyping of Generics",[20,21,23],"code-wrapper",{"language":22},"scala",[24,25,29],"pre",{"className":26,"code":27,"language":22,"meta":28,"style":28},"language-scala shiki shiki-themes github-light github-dark","\u002F\u002F Variance controls whether C[Sub] is a subtype of C[Super].\n\n\u002F\u002F INVARIANT [T] (default): C[Sub] is NOT a subtype of C[Super]\n\u002F\u002F   Safe: can read AND write T. Used for mutable collections.\nclass MutableBox[T](var value: T)\n\u002F\u002F MutableBox[Dog] is NOT a MutableBox[Animal] — adding a Cat would corrupt it.\n\n\u002F\u002F COVARIANT [+T]: if Sub \u003C: Super, then C[Sub] \u003C: C[Super]\n\u002F\u002F   Safe: can only READ T (produce\u002Freturn), never write (consume\u002Faccept).\n\u002F\u002F   Used for immutable collections, producers, return types.\nclass ImmutableList[+T]                                  \u002F\u002F List[Dog] \u003C: List[Animal] ✅\n\u002F\u002F ImmutableList[Dog].head: Animal ← safe, a Dog IS an Animal\n\u002F\u002F Cannot have def append(t: T) — would allow adding Cat to List[Dog]\n\n\u002F\u002F CONTRAVARIANT [-T]: if Sub \u003C: Super, then C[Super] \u003C: C[Sub] (INVERTED)\n\u002F\u002F   Safe: can only WRITE T (consume\u002Faccept), never read (produce\u002Freturn).\n\u002F\u002F   Used for consumers, function parameters, comparators.\ntrait Comparator[-T]:\n  def compare(a: T, b: T): Int\n\u002F\u002F Comparator[Animal] \u003C: Comparator[Dog] ← safe, comparing Dogs as Animals is fine\n\u002F\u002F A function Animal => String is a subtype of Dog => String:\nval f: Animal => String = a => a.name\nval g: Dog => String = f                  \u002F\u002F OK! Function1 is contravariant in its parameter\n\n\u002F\u002F The variance positions rule (the \"in\u002Fout\" rule):\n\u002F\u002F   +T: T can appear in RETURN positions (out), never in parameter positions (in)\n\u002F\u002F   -T: T can appear in PARAMETER positions (in), never in return positions (out)\n\u002F\u002F    T: T can appear anywhere (both in and out)\n","",[30,31,32,41,48,54,60,97,103,108,114,120,126,147,153,159,164,170,176,182,204,242,248,254,286,311,316,322,328,334],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sdCPZ","\u002F\u002F Variance controls whether C[Sub] is a subtype of C[Super].\n",[33,42,44],{"class":35,"line":43},2,[33,45,47],{"emptyLinePlaceholder":46},true,"\n",[33,49,51],{"class":35,"line":50},3,[33,52,53],{"class":39},"\u002F\u002F INVARIANT [T] (default): C[Sub] is NOT a subtype of C[Super]\n",[33,55,57],{"class":35,"line":56},4,[33,58,59],{"class":39},"\u002F\u002F   Safe: can read AND write T. Used for mutable collections.\n",[33,61,63,67,71,75,78,81,84,88,91,94],{"class":35,"line":62},5,[33,64,66],{"class":65},"svdQ7","class",[33,68,70],{"class":69},"sIsaT"," MutableBox",[33,72,74],{"class":73},"ssxIu","[",[33,76,77],{"class":69},"T",[33,79,80],{"class":73},"](",[33,82,83],{"class":65},"var",[33,85,87],{"class":86},"sCrzJ"," value",[33,89,90],{"class":65},":",[33,92,93],{"class":69}," T",[33,95,96],{"class":73},")\n",[33,98,100],{"class":35,"line":99},6,[33,101,102],{"class":39},"\u002F\u002F MutableBox[Dog] is NOT a MutableBox[Animal] — adding a Cat would corrupt it.\n",[33,104,106],{"class":35,"line":105},7,[33,107,47],{"emptyLinePlaceholder":46},[33,109,111],{"class":35,"line":110},8,[33,112,113],{"class":39},"\u002F\u002F COVARIANT [+T]: if Sub \u003C: Super, then C[Sub] \u003C: C[Super]\n",[33,115,117],{"class":35,"line":116},9,[33,118,119],{"class":39},"\u002F\u002F   Safe: can only READ T (produce\u002Freturn), never write (consume\u002Faccept).\n",[33,121,123],{"class":35,"line":122},10,[33,124,125],{"class":39},"\u002F\u002F   Used for immutable collections, producers, return types.\n",[33,127,129,131,134,136,139,141,144],{"class":35,"line":128},11,[33,130,66],{"class":65},[33,132,133],{"class":69}," ImmutableList",[33,135,74],{"class":73},[33,137,138],{"class":65},"+",[33,140,77],{"class":69},[33,142,143],{"class":73},"]                                  ",[33,145,146],{"class":39},"\u002F\u002F List[Dog] \u003C: List[Animal] ✅\n",[33,148,150],{"class":35,"line":149},12,[33,151,152],{"class":39},"\u002F\u002F ImmutableList[Dog].head: Animal ← safe, a Dog IS an Animal\n",[33,154,156],{"class":35,"line":155},13,[33,157,158],{"class":39},"\u002F\u002F Cannot have def append(t: T) — would allow adding Cat to List[Dog]\n",[33,160,162],{"class":35,"line":161},14,[33,163,47],{"emptyLinePlaceholder":46},[33,165,167],{"class":35,"line":166},15,[33,168,169],{"class":39},"\u002F\u002F CONTRAVARIANT [-T]: if Sub \u003C: Super, then C[Super] \u003C: C[Sub] (INVERTED)\n",[33,171,173],{"class":35,"line":172},16,[33,174,175],{"class":39},"\u002F\u002F   Safe: can only WRITE T (consume\u002Faccept), never read (produce\u002Freturn).\n",[33,177,179],{"class":35,"line":178},17,[33,180,181],{"class":39},"\u002F\u002F   Used for consumers, function parameters, comparators.\n",[33,183,185,188,191,193,196,198,201],{"class":35,"line":184},18,[33,186,187],{"class":65},"trait",[33,189,190],{"class":69}," Comparator",[33,192,74],{"class":73},[33,194,195],{"class":65},"-",[33,197,77],{"class":69},[33,199,200],{"class":73},"]",[33,202,203],{"class":65},":\n",[33,205,207,210,213,216,219,222,224,227,230,232,234,237,239],{"class":35,"line":206},19,[33,208,209],{"class":65},"  def",[33,211,212],{"class":69}," compare",[33,214,215],{"class":73},"(",[33,217,218],{"class":86},"a",[33,220,221],{"class":73},": ",[33,223,77],{"class":69},[33,225,226],{"class":73},", ",[33,228,229],{"class":86},"b",[33,231,221],{"class":73},[33,233,77],{"class":69},[33,235,236],{"class":73},")",[33,238,90],{"class":65},[33,240,241],{"class":69}," Int\n",[33,243,245],{"class":35,"line":244},20,[33,246,247],{"class":39},"\u002F\u002F Comparator[Animal] \u003C: Comparator[Dog] ← safe, comparing Dogs as Animals is fine\n",[33,249,251],{"class":35,"line":250},21,[33,252,253],{"class":39},"\u002F\u002F A function Animal => String is a subtype of Dog => String:\n",[33,255,257,260,263,265,268,271,274,277,280,283],{"class":35,"line":256},22,[33,258,259],{"class":65},"val",[33,261,262],{"class":86}," f",[33,264,90],{"class":65},[33,266,267],{"class":69}," Animal",[33,269,270],{"class":65}," =>",[33,272,273],{"class":69}," String",[33,275,276],{"class":65}," =",[33,278,279],{"class":73}," a ",[33,281,282],{"class":65},"=>",[33,284,285],{"class":73}," a.name\n",[33,287,289,291,294,296,299,301,303,305,308],{"class":35,"line":288},23,[33,290,259],{"class":65},[33,292,293],{"class":86}," g",[33,295,90],{"class":65},[33,297,298],{"class":69}," Dog",[33,300,270],{"class":65},[33,302,273],{"class":69},[33,304,276],{"class":65},[33,306,307],{"class":73}," f                  ",[33,309,310],{"class":39},"\u002F\u002F OK! Function1 is contravariant in its parameter\n",[33,312,314],{"class":35,"line":313},24,[33,315,47],{"emptyLinePlaceholder":46},[33,317,319],{"class":35,"line":318},25,[33,320,321],{"class":39},"\u002F\u002F The variance positions rule (the \"in\u002Fout\" rule):\n",[33,323,325],{"class":35,"line":324},26,[33,326,327],{"class":39},"\u002F\u002F   +T: T can appear in RETURN positions (out), never in parameter positions (in)\n",[33,329,331],{"class":35,"line":330},27,[33,332,333],{"class":39},"\u002F\u002F   -T: T can appear in PARAMETER positions (in), never in return positions (out)\n",[33,335,337],{"class":35,"line":336},28,[33,338,339],{"class":39},"\u002F\u002F    T: T can appear anywhere (both in and out)\n",[15,341,343],{"id":342},"variance-constraints-the-lower-bound-trick","Variance Constraints — The Lower Bound Trick",[20,345,346],{"language":22},[24,347,349],{"className":26,"code":348,"language":22,"meta":28,"style":28},"\u002F\u002F Problem: covariant List[+T] needs a \"prepend\" method, but prepend takes T as a\n\u002F\u002F parameter (contravariant position) — conflicts with +T variance.\n\u002F\u002F\n\u002F\u002F Solution: lower bound on the type parameter\nclass MyList[+T]:\n  \u002F\u002F def prepend(t: T): MyList[T]  ← COMPILE ERROR: covariant T in contravariant position\n  def prepend[U >: T](u: U): MyList[U] = ???  \u002F\u002F ✅ U is a supertype of T, T appears in covariant position\n\n\u002F\u002F When you prepend a Cat to a MyList[Dog]:\n\u002F\u002F   U = LUB(Cat, Dog) = Animal\n\u002F\u002F   Result: MyList[Animal]\n\u002F\u002F This is EXACTLY how List's :: works — it widens the element type as needed.\n\nval dogs: MyList[Dog] = MyList(dog1, dog2)\nval animals: MyList[Animal] = dogs.prepend(cat1)  \u002F\u002F U=Animal, returns MyList[Animal]\n\n\u002F\u002F ❌ ANTI-PATTERN: making a mutable collection covariant\n\u002F\u002F class MutList[+T](var head: T)  ← COMPILE ERROR: covariant T in var (contravariant position)\n\u002F\u002F Because var generates both getter (covariant) AND setter (contravariant) — conflicting.\n",[30,350,351,356,361,366,371,388,393,441,445,450,455,460,465,469,494,520,524,529,534],{"__ignoreMap":28},[33,352,353],{"class":35,"line":36},[33,354,355],{"class":39},"\u002F\u002F Problem: covariant List[+T] needs a \"prepend\" method, but prepend takes T as a\n",[33,357,358],{"class":35,"line":43},[33,359,360],{"class":39},"\u002F\u002F parameter (contravariant position) — conflicts with +T variance.\n",[33,362,363],{"class":35,"line":50},[33,364,365],{"class":39},"\u002F\u002F\n",[33,367,368],{"class":35,"line":56},[33,369,370],{"class":39},"\u002F\u002F Solution: lower bound on the type parameter\n",[33,372,373,375,378,380,382,384,386],{"class":35,"line":62},[33,374,66],{"class":65},[33,376,377],{"class":69}," MyList",[33,379,74],{"class":73},[33,381,138],{"class":65},[33,383,77],{"class":69},[33,385,200],{"class":73},[33,387,203],{"class":65},[33,389,390],{"class":35,"line":99},[33,391,392],{"class":39},"  \u002F\u002F def prepend(t: T): MyList[T]  ← COMPILE ERROR: covariant T in contravariant position\n",[33,394,395,397,400,402,405,408,410,412,415,417,419,421,423,425,427,429,432,435,438],{"class":35,"line":105},[33,396,209],{"class":65},[33,398,399],{"class":69}," prepend",[33,401,74],{"class":73},[33,403,404],{"class":69},"U",[33,406,407],{"class":65}," >:",[33,409,93],{"class":69},[33,411,80],{"class":73},[33,413,414],{"class":86},"u",[33,416,221],{"class":73},[33,418,404],{"class":69},[33,420,236],{"class":73},[33,422,90],{"class":65},[33,424,377],{"class":69},[33,426,74],{"class":73},[33,428,404],{"class":69},[33,430,431],{"class":73},"] ",[33,433,434],{"class":65},"=",[33,436,437],{"class":65}," ???",[33,439,440],{"class":39},"  \u002F\u002F ✅ U is a supertype of T, T appears in covariant position\n",[33,442,443],{"class":35,"line":110},[33,444,47],{"emptyLinePlaceholder":46},[33,446,447],{"class":35,"line":116},[33,448,449],{"class":39},"\u002F\u002F When you prepend a Cat to a MyList[Dog]:\n",[33,451,452],{"class":35,"line":122},[33,453,454],{"class":39},"\u002F\u002F   U = LUB(Cat, Dog) = Animal\n",[33,456,457],{"class":35,"line":128},[33,458,459],{"class":39},"\u002F\u002F   Result: MyList[Animal]\n",[33,461,462],{"class":35,"line":149},[33,463,464],{"class":39},"\u002F\u002F This is EXACTLY how List's :: works — it widens the element type as needed.\n",[33,466,467],{"class":35,"line":155},[33,468,47],{"emptyLinePlaceholder":46},[33,470,471,473,476,478,480,482,485,487,489,491],{"class":35,"line":161},[33,472,259],{"class":65},[33,474,475],{"class":86}," dogs",[33,477,90],{"class":65},[33,479,377],{"class":69},[33,481,74],{"class":73},[33,483,484],{"class":69},"Dog",[33,486,431],{"class":73},[33,488,434],{"class":65},[33,490,377],{"class":69},[33,492,493],{"class":73},"(dog1, dog2)\n",[33,495,496,498,501,503,505,507,510,512,514,517],{"class":35,"line":166},[33,497,259],{"class":65},[33,499,500],{"class":86}," animals",[33,502,90],{"class":65},[33,504,377],{"class":69},[33,506,74],{"class":73},[33,508,509],{"class":69},"Animal",[33,511,431],{"class":73},[33,513,434],{"class":65},[33,515,516],{"class":73}," dogs.prepend(cat1)  ",[33,518,519],{"class":39},"\u002F\u002F U=Animal, returns MyList[Animal]\n",[33,521,522],{"class":35,"line":172},[33,523,47],{"emptyLinePlaceholder":46},[33,525,526],{"class":35,"line":178},[33,527,528],{"class":39},"\u002F\u002F ❌ ANTI-PATTERN: making a mutable collection covariant\n",[33,530,531],{"class":35,"line":184},[33,532,533],{"class":39},"\u002F\u002F class MutList[+T](var head: T)  ← COMPILE ERROR: covariant T in var (contravariant position)\n",[33,535,536],{"class":35,"line":206},[33,537,538],{"class":39},"\u002F\u002F Because var generates both getter (covariant) AND setter (contravariant) — conflicting.\n",[15,540,542,543,546,547,550],{"id":541},"type-classes-with-given-using-scala-3","Type Classes with ",[30,544,545],{},"given"," \u002F ",[30,548,549],{},"using"," — Scala 3",[20,552,553],{"language":22},[24,554,556],{"className":26,"code":555,"language":22,"meta":28,"style":28},"\u002F\u002F Type class: a trait parameterized by a type, with instances provided via 'given'.\n\u002F\u002F This is ad-hoc polymorphism — different behavior per type, without inheritance.\n\ntrait Show[T]:\n  extension (t: T) def show: String\n\ntrait Eq[T]:\n  extension (t: T) def ===(other: T): Boolean\n\n\u002F\u002F Instances — provided as 'given' values, resolved by the compiler via 'using'\ngiven Show[Int] with\n  extension (t: Int) def show: String = s\"Int($t)\"\n\ngiven Show[String] with\n  extension (t: String) def show: String = s\"\"\"\"$t\"\"\"\"\n\ngiven Show[Boolean] with\n  extension (t: Boolean) def show: String = t.toString\n\n\u002F\u002F Usage — 'using' parameter is resolved automatically from the given scope\ndef printAll[T](values: List[T])(using s: Show[T]): Unit =\n  values.foreach(v => println(s.show(v)))  \u002F\u002F or: v.show (extension method via the given)\n\nprintAll(List(1, 2, 3))                     \u002F\u002F → Int(1), Int(2), Int(3) — Show[Int] resolved\nprintAll(List(\"a\", \"b\"))                    \u002F\u002F → \"a\", \"b\" — Show[String] resolved\n\n\u002F\u002F Context-bound sugar: [T: Show] means (using Show[T])\ndef serialize[T: Show](t: T): String = summon[Show[T]].show(t)\n\u002F\u002F summon[Show[T]] retrieves the given instance from scope\n",[30,557,558,563,568,572,587,616,620,635,670,674,679,695,732,736,751,785,789,804,831,835,840,892,905,909,938,960,964,969,1012],{"__ignoreMap":28},[33,559,560],{"class":35,"line":36},[33,561,562],{"class":39},"\u002F\u002F Type class: a trait parameterized by a type, with instances provided via 'given'.\n",[33,564,565],{"class":35,"line":43},[33,566,567],{"class":39},"\u002F\u002F This is ad-hoc polymorphism — different behavior per type, without inheritance.\n",[33,569,570],{"class":35,"line":50},[33,571,47],{"emptyLinePlaceholder":46},[33,573,574,576,579,581,583,585],{"class":35,"line":56},[33,575,187],{"class":65},[33,577,578],{"class":69}," Show",[33,580,74],{"class":73},[33,582,77],{"class":69},[33,584,200],{"class":73},[33,586,203],{"class":65},[33,588,589,592,595,598,600,602,605,608,611,613],{"class":35,"line":62},[33,590,591],{"class":65},"  extension",[33,593,594],{"class":73}," (",[33,596,597],{"class":86},"t",[33,599,221],{"class":73},[33,601,77],{"class":69},[33,603,604],{"class":73},") ",[33,606,607],{"class":65},"def",[33,609,610],{"class":69}," show",[33,612,90],{"class":65},[33,614,615],{"class":69}," String\n",[33,617,618],{"class":35,"line":99},[33,619,47],{"emptyLinePlaceholder":46},[33,621,622,624,627,629,631,633],{"class":35,"line":105},[33,623,187],{"class":65},[33,625,626],{"class":69}," Eq",[33,628,74],{"class":73},[33,630,77],{"class":69},[33,632,200],{"class":73},[33,634,203],{"class":65},[33,636,637,639,641,643,645,647,649,651,654,656,659,661,663,665,667],{"class":35,"line":110},[33,638,591],{"class":65},[33,640,594],{"class":73},[33,642,597],{"class":86},[33,644,221],{"class":73},[33,646,77],{"class":69},[33,648,604],{"class":73},[33,650,607],{"class":65},[33,652,653],{"class":69}," ===",[33,655,215],{"class":73},[33,657,658],{"class":86},"other",[33,660,221],{"class":73},[33,662,77],{"class":69},[33,664,236],{"class":73},[33,666,90],{"class":65},[33,668,669],{"class":69}," Boolean\n",[33,671,672],{"class":35,"line":116},[33,673,47],{"emptyLinePlaceholder":46},[33,675,676],{"class":35,"line":122},[33,677,678],{"class":39},"\u002F\u002F Instances — provided as 'given' values, resolved by the compiler via 'using'\n",[33,680,681,683,685,687,690,692],{"class":35,"line":128},[33,682,545],{"class":65},[33,684,578],{"class":69},[33,686,74],{"class":73},[33,688,689],{"class":69},"Int",[33,691,431],{"class":73},[33,693,694],{"class":65},"with\n",[33,696,697,699,701,703,705,707,709,711,713,715,717,719,722,726,729],{"class":35,"line":149},[33,698,591],{"class":65},[33,700,594],{"class":73},[33,702,597],{"class":86},[33,704,221],{"class":73},[33,706,689],{"class":69},[33,708,604],{"class":73},[33,710,607],{"class":65},[33,712,610],{"class":69},[33,714,90],{"class":65},[33,716,273],{"class":69},[33,718,276],{"class":65},[33,720,721],{"class":65}," s",[33,723,725],{"class":724},"sJ6F3","\"Int(",[33,727,728],{"class":73},"$t",[33,730,731],{"class":724},")\"\n",[33,733,734],{"class":35,"line":155},[33,735,47],{"emptyLinePlaceholder":46},[33,737,738,740,742,744,747,749],{"class":35,"line":161},[33,739,545],{"class":65},[33,741,578],{"class":69},[33,743,74],{"class":73},[33,745,746],{"class":69},"String",[33,748,431],{"class":73},[33,750,694],{"class":65},[33,752,753,755,757,759,761,763,765,767,769,771,773,775,777,780,782],{"class":35,"line":166},[33,754,591],{"class":65},[33,756,594],{"class":73},[33,758,597],{"class":86},[33,760,221],{"class":73},[33,762,746],{"class":69},[33,764,604],{"class":73},[33,766,607],{"class":65},[33,768,610],{"class":69},[33,770,90],{"class":65},[33,772,273],{"class":69},[33,774,276],{"class":65},[33,776,721],{"class":65},[33,778,779],{"class":724},"\"\"\"\"",[33,781,728],{"class":73},[33,783,784],{"class":724},"\"\"\"\"\n",[33,786,787],{"class":35,"line":172},[33,788,47],{"emptyLinePlaceholder":46},[33,790,791,793,795,797,800,802],{"class":35,"line":178},[33,792,545],{"class":65},[33,794,578],{"class":69},[33,796,74],{"class":73},[33,798,799],{"class":69},"Boolean",[33,801,431],{"class":73},[33,803,694],{"class":65},[33,805,806,808,810,812,814,816,818,820,822,824,826,828],{"class":35,"line":184},[33,807,591],{"class":65},[33,809,594],{"class":73},[33,811,597],{"class":86},[33,813,221],{"class":73},[33,815,799],{"class":69},[33,817,604],{"class":73},[33,819,607],{"class":65},[33,821,610],{"class":69},[33,823,90],{"class":65},[33,825,273],{"class":69},[33,827,276],{"class":65},[33,829,830],{"class":73}," t.toString\n",[33,832,833],{"class":35,"line":206},[33,834,47],{"emptyLinePlaceholder":46},[33,836,837],{"class":35,"line":244},[33,838,839],{"class":39},"\u002F\u002F Usage — 'using' parameter is resolved automatically from the given scope\n",[33,841,842,844,847,849,851,853,856,858,861,863,865,868,870,872,874,877,879,881,884,886,889],{"class":35,"line":250},[33,843,607],{"class":65},[33,845,846],{"class":69}," printAll",[33,848,74],{"class":73},[33,850,77],{"class":69},[33,852,80],{"class":73},[33,854,855],{"class":86},"values",[33,857,221],{"class":73},[33,859,860],{"class":69},"List",[33,862,74],{"class":73},[33,864,77],{"class":69},[33,866,867],{"class":73},"])(",[33,869,549],{"class":65},[33,871,721],{"class":86},[33,873,221],{"class":73},[33,875,876],{"class":69},"Show",[33,878,74],{"class":73},[33,880,77],{"class":69},[33,882,883],{"class":73},"])",[33,885,90],{"class":65},[33,887,888],{"class":69}," Unit",[33,890,891],{"class":65}," =\n",[33,893,894,897,899,902],{"class":35,"line":256},[33,895,896],{"class":73},"  values.foreach(v ",[33,898,282],{"class":65},[33,900,901],{"class":73}," println(s.show(v)))  ",[33,903,904],{"class":39},"\u002F\u002F or: v.show (extension method via the given)\n",[33,906,907],{"class":35,"line":288},[33,908,47],{"emptyLinePlaceholder":46},[33,910,911,914,916,918,922,924,927,929,932,935],{"class":35,"line":313},[33,912,913],{"class":73},"printAll(",[33,915,860],{"class":69},[33,917,215],{"class":73},[33,919,921],{"class":920},"snvgF","1",[33,923,226],{"class":73},[33,925,926],{"class":920},"2",[33,928,226],{"class":73},[33,930,931],{"class":920},"3",[33,933,934],{"class":73},"))                     ",[33,936,937],{"class":39},"\u002F\u002F → Int(1), Int(2), Int(3) — Show[Int] resolved\n",[33,939,940,942,944,946,949,951,954,957],{"class":35,"line":318},[33,941,913],{"class":73},[33,943,860],{"class":69},[33,945,215],{"class":73},[33,947,948],{"class":724},"\"a\"",[33,950,226],{"class":73},[33,952,953],{"class":724},"\"b\"",[33,955,956],{"class":73},"))                    ",[33,958,959],{"class":39},"\u002F\u002F → \"a\", \"b\" — Show[String] resolved\n",[33,961,962],{"class":35,"line":324},[33,963,47],{"emptyLinePlaceholder":46},[33,965,966],{"class":35,"line":330},[33,967,968],{"class":39},"\u002F\u002F Context-bound sugar: [T: Show] means (using Show[T])\n",[33,970,971,973,976,978,980,982,984,986,988,990,992,994,996,998,1000,1003,1005,1007,1009],{"class":35,"line":336},[33,972,607],{"class":65},[33,974,975],{"class":69}," serialize",[33,977,74],{"class":73},[33,979,77],{"class":69},[33,981,90],{"class":65},[33,983,578],{"class":69},[33,985,80],{"class":73},[33,987,597],{"class":86},[33,989,221],{"class":73},[33,991,77],{"class":69},[33,993,236],{"class":73},[33,995,90],{"class":65},[33,997,273],{"class":69},[33,999,276],{"class":65},[33,1001,1002],{"class":73}," summon[",[33,1004,876],{"class":69},[33,1006,74],{"class":73},[33,1008,77],{"class":69},[33,1010,1011],{"class":73},"]].show(t)\n",[33,1013,1015],{"class":35,"line":1014},29,[33,1016,1017],{"class":39},"\u002F\u002F summon[Show[T]] retrieves the given instance from scope\n",[15,1019,1021],{"id":1020},"type-class-instance-resolution-priority-scope","Type Class Instance Resolution — Priority & Scope",[20,1023,1024],{"language":22},[24,1025,1027],{"className":26,"code":1026,"language":22,"meta":28,"style":28},"\u002F\u002F Given instances are resolved by the compiler in this priority order:\n\u002F\u002F   1. Explicitly passed: f(using myInstance)\n\u002F\u002F   2. Local given in the current scope\n\u002F\u002F   3. Given in the companion object of the type class (Show)\n\u002F\u002F   4. Given in the companion object of the type (Show[Int] in Int's companion — can't do for Int)\n\u002F\u002F   5. Imported givings: import MyGivens.*\n\n\u002F\u002F Ambiguous givens → compile error\ngiven Show[Int] with extension (t: Int) def show = t.toString\ngiven Show[Int] with extension (t: Int) def show = s\"int=$t\"\n\u002F\u002F serialize(42) → ERROR: ambiguous givens: both Show[Int] instances match\n\n\u002F\u002F Organize givens in companion objects for automatic availability:\nobject Show:\n  given Show[Int] with extension (t: Int) def show = t.toString\n  given Show[String] with extension (t: String) def show = s\"\"\"\"$t\"\"\"\"\n  given [T: Show] => Show[List[T]] with           \u002F\u002F conditional instance — needs Show[T]\n    extension (list: List[T]) def show =\n      list.map(_.show).mkString(\"[\", \",\", \"]\")\n\n\u002F\u002F Now Show[List[Int]] is auto-derived from Show[Int] — no manual instance needed\nserialize(List(1, 2, 3))                   \u002F\u002F → \"[1,2,3]\"\n",[30,1028,1029,1034,1039,1044,1049,1054,1059,1063,1068,1102,1142,1147,1151,1156,1165,1198,1236,1271,1298,1318,1322,1327],{"__ignoreMap":28},[33,1030,1031],{"class":35,"line":36},[33,1032,1033],{"class":39},"\u002F\u002F Given instances are resolved by the compiler in this priority order:\n",[33,1035,1036],{"class":35,"line":43},[33,1037,1038],{"class":39},"\u002F\u002F   1. Explicitly passed: f(using myInstance)\n",[33,1040,1041],{"class":35,"line":50},[33,1042,1043],{"class":39},"\u002F\u002F   2. Local given in the current scope\n",[33,1045,1046],{"class":35,"line":56},[33,1047,1048],{"class":39},"\u002F\u002F   3. Given in the companion object of the type class (Show)\n",[33,1050,1051],{"class":35,"line":62},[33,1052,1053],{"class":39},"\u002F\u002F   4. Given in the companion object of the type (Show[Int] in Int's companion — can't do for Int)\n",[33,1055,1056],{"class":35,"line":99},[33,1057,1058],{"class":39},"\u002F\u002F   5. Imported givings: import MyGivens.*\n",[33,1060,1061],{"class":35,"line":105},[33,1062,47],{"emptyLinePlaceholder":46},[33,1064,1065],{"class":35,"line":110},[33,1066,1067],{"class":39},"\u002F\u002F Ambiguous givens → compile error\n",[33,1069,1070,1072,1074,1076,1078,1080,1083,1086,1088,1090,1092,1094,1096,1098,1100],{"class":35,"line":116},[33,1071,545],{"class":65},[33,1073,578],{"class":69},[33,1075,74],{"class":73},[33,1077,689],{"class":69},[33,1079,431],{"class":73},[33,1081,1082],{"class":65},"with",[33,1084,1085],{"class":73}," extension (",[33,1087,597],{"class":86},[33,1089,221],{"class":73},[33,1091,689],{"class":69},[33,1093,604],{"class":73},[33,1095,607],{"class":65},[33,1097,610],{"class":69},[33,1099,276],{"class":65},[33,1101,830],{"class":73},[33,1103,1104,1106,1108,1110,1112,1114,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1137,1139],{"class":35,"line":122},[33,1105,545],{"class":65},[33,1107,578],{"class":69},[33,1109,74],{"class":73},[33,1111,689],{"class":69},[33,1113,431],{"class":73},[33,1115,1082],{"class":65},[33,1117,1085],{"class":73},[33,1119,597],{"class":86},[33,1121,221],{"class":73},[33,1123,689],{"class":69},[33,1125,604],{"class":73},[33,1127,607],{"class":65},[33,1129,610],{"class":69},[33,1131,276],{"class":65},[33,1133,721],{"class":65},[33,1135,1136],{"class":724},"\"int=",[33,1138,728],{"class":73},[33,1140,1141],{"class":724},"\"\n",[33,1143,1144],{"class":35,"line":128},[33,1145,1146],{"class":39},"\u002F\u002F serialize(42) → ERROR: ambiguous givens: both Show[Int] instances match\n",[33,1148,1149],{"class":35,"line":149},[33,1150,47],{"emptyLinePlaceholder":46},[33,1152,1153],{"class":35,"line":155},[33,1154,1155],{"class":39},"\u002F\u002F Organize givens in companion objects for automatic availability:\n",[33,1157,1158,1161,1163],{"class":35,"line":161},[33,1159,1160],{"class":65},"object",[33,1162,578],{"class":69},[33,1164,203],{"class":65},[33,1166,1167,1170,1172,1174,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196],{"class":35,"line":166},[33,1168,1169],{"class":65},"  given",[33,1171,578],{"class":69},[33,1173,74],{"class":73},[33,1175,689],{"class":69},[33,1177,431],{"class":73},[33,1179,1082],{"class":65},[33,1181,1085],{"class":73},[33,1183,597],{"class":86},[33,1185,221],{"class":73},[33,1187,689],{"class":69},[33,1189,604],{"class":73},[33,1191,607],{"class":65},[33,1193,610],{"class":69},[33,1195,276],{"class":65},[33,1197,830],{"class":73},[33,1199,1200,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228,1230,1232,1234],{"class":35,"line":172},[33,1201,1169],{"class":65},[33,1203,578],{"class":69},[33,1205,74],{"class":73},[33,1207,746],{"class":69},[33,1209,431],{"class":73},[33,1211,1082],{"class":65},[33,1213,1085],{"class":73},[33,1215,597],{"class":86},[33,1217,221],{"class":73},[33,1219,746],{"class":69},[33,1221,604],{"class":73},[33,1223,607],{"class":65},[33,1225,610],{"class":69},[33,1227,276],{"class":65},[33,1229,721],{"class":65},[33,1231,779],{"class":724},[33,1233,728],{"class":73},[33,1235,784],{"class":724},[33,1237,1238,1240,1243,1245,1247,1249,1251,1253,1255,1257,1259,1261,1263,1266,1268],{"class":35,"line":178},[33,1239,1169],{"class":65},[33,1241,1242],{"class":73}," [",[33,1244,77],{"class":69},[33,1246,90],{"class":65},[33,1248,578],{"class":69},[33,1250,431],{"class":73},[33,1252,282],{"class":65},[33,1254,578],{"class":69},[33,1256,74],{"class":73},[33,1258,860],{"class":69},[33,1260,74],{"class":73},[33,1262,77],{"class":69},[33,1264,1265],{"class":73},"]] ",[33,1267,1082],{"class":65},[33,1269,1270],{"class":39},"           \u002F\u002F conditional instance — needs Show[T]\n",[33,1272,1273,1276,1278,1281,1283,1285,1287,1289,1292,1294,1296],{"class":35,"line":184},[33,1274,1275],{"class":65},"    extension",[33,1277,594],{"class":73},[33,1279,1280],{"class":86},"list",[33,1282,221],{"class":73},[33,1284,860],{"class":69},[33,1286,74],{"class":73},[33,1288,77],{"class":69},[33,1290,1291],{"class":73},"]) ",[33,1293,607],{"class":65},[33,1295,610],{"class":69},[33,1297,891],{"class":65},[33,1299,1300,1303,1306,1308,1311,1313,1316],{"class":35,"line":206},[33,1301,1302],{"class":73},"      list.map(_.show).mkString(",[33,1304,1305],{"class":724},"\"[\"",[33,1307,226],{"class":73},[33,1309,1310],{"class":724},"\",\"",[33,1312,226],{"class":73},[33,1314,1315],{"class":724},"\"]\"",[33,1317,96],{"class":73},[33,1319,1320],{"class":35,"line":244},[33,1321,47],{"emptyLinePlaceholder":46},[33,1323,1324],{"class":35,"line":250},[33,1325,1326],{"class":39},"\u002F\u002F Now Show[List[Int]] is auto-derived from Show[Int] — no manual instance needed\n",[33,1328,1329,1332,1334,1336,1338,1340,1342,1344,1346,1349],{"class":35,"line":256},[33,1330,1331],{"class":73},"serialize(",[33,1333,860],{"class":69},[33,1335,215],{"class":73},[33,1337,921],{"class":920},[33,1339,226],{"class":73},[33,1341,926],{"class":920},[33,1343,226],{"class":73},[33,1345,931],{"class":920},[33,1347,1348],{"class":73},"))                   ",[33,1350,1351],{"class":39},"\u002F\u002F → \"[1,2,3]\"\n",[15,1353,1355,1356],{"id":1354},"higher-kinded-types-f_","Higher-Kinded Types — ",[30,1357,1358],{},"F[_]",[20,1360,1361],{"language":22},[24,1362,1364],{"className":26,"code":1363,"language":22,"meta":28,"style":28},"\u002F\u002F Higher-kinded type: a type constructor that takes a type parameter.\n\u002F\u002F List is * → * (takes one type, produces one type). List[Int] is a concrete type.\n\n\u002F\u002F Functor: a type class for things you can map over\ntrait Functor[F[_]]:\n  extension [A](fa: F[A]) def map[B](f: A => B): F[B]\n\ngiven Functor[List] with\n  extension [A](fa: List[A]) def map[B](f: A => B): List[B] = fa.map(f)\n\ngiven Functor[Option] with\n  extension [A](fa: Option[A]) def map[B](f: A => B): Option[B] = fa.map(f)\n\n\u002F\u002F Usage: works on ANY functor, regardless of concrete type\ndef doubleAll[F[_]: Functor](fa: F[Int]): F[Int] = fa.map(_ * 2)\ndoubleAll(List(1, 2, 3))                    \u002F\u002F → List(2, 4, 6)\ndoubleAll(Some(42))                         \u002F\u002F → Some(84)\ndoubleAll(None)                             \u002F\u002F → None\n\n\u002F\u002F Monad: extends Functor with flatMap (sequencing)\ntrait Monad[F[_]] extends Functor[F]:\n  extension [A](fa: F[A])\n    def flatMap[B](f: A => F[B]): F[B]\n    def map[B](f: A => B): F[B] = flatMap(a => pure(f(a)))\n  def pure[A](a: A): F[A]\n\ngiven Monad[Option] with\n  extension [A](fa: Option[A])\n    def flatMap[B](f: A => Option[B]): Option[B] = fa.flatMap(f)\n  def pure[A](a: A): Option[A] = Some(a)\n\n\u002F\u002F Generic monadic computation — works for Option, List, Future, IO, etc.\ndef compose[F[_]: Monad, A, B, C](f: A => F[B], g: B => F[C])(a: A): F[C] =\n  f(a).flatMap(g)                           \u002F\u002F no knowledge of F's concrete type\n",[30,1365,1366,1371,1376,1380,1385,1402,1464,1468,1482,1542,1546,1561,1620,1624,1629,1684,1708,1726,1739,1743,1748,1775,1798,1838,1882,1913,1917,1931,1953,1996,2035,2040,2046,2134],{"__ignoreMap":28},[33,1367,1368],{"class":35,"line":36},[33,1369,1370],{"class":39},"\u002F\u002F Higher-kinded type: a type constructor that takes a type parameter.\n",[33,1372,1373],{"class":35,"line":43},[33,1374,1375],{"class":39},"\u002F\u002F List is * → * (takes one type, produces one type). List[Int] is a concrete type.\n",[33,1377,1378],{"class":35,"line":50},[33,1379,47],{"emptyLinePlaceholder":46},[33,1381,1382],{"class":35,"line":56},[33,1383,1384],{"class":39},"\u002F\u002F Functor: a type class for things you can map over\n",[33,1386,1387,1389,1392,1394,1397,1400],{"class":35,"line":62},[33,1388,187],{"class":65},[33,1390,1391],{"class":69}," Functor",[33,1393,74],{"class":73},[33,1395,1396],{"class":69},"F",[33,1398,1399],{"class":73},"[_]]",[33,1401,203],{"class":65},[33,1403,1404,1406,1408,1411,1413,1416,1418,1420,1422,1424,1426,1428,1431,1433,1436,1438,1441,1443,1445,1447,1450,1452,1454,1457,1459,1461],{"class":35,"line":99},[33,1405,591],{"class":65},[33,1407,1242],{"class":73},[33,1409,1410],{"class":69},"A",[33,1412,80],{"class":73},[33,1414,1415],{"class":86},"fa",[33,1417,221],{"class":73},[33,1419,1396],{"class":69},[33,1421,74],{"class":73},[33,1423,1410],{"class":69},[33,1425,1291],{"class":73},[33,1427,607],{"class":65},[33,1429,1430],{"class":69}," map",[33,1432,74],{"class":73},[33,1434,1435],{"class":69},"B",[33,1437,80],{"class":73},[33,1439,1440],{"class":86},"f",[33,1442,221],{"class":73},[33,1444,1410],{"class":69},[33,1446,270],{"class":65},[33,1448,1449],{"class":69}," B",[33,1451,236],{"class":73},[33,1453,90],{"class":65},[33,1455,1456],{"class":69}," F",[33,1458,74],{"class":73},[33,1460,1435],{"class":69},[33,1462,1463],{"class":73},"]\n",[33,1465,1466],{"class":35,"line":105},[33,1467,47],{"emptyLinePlaceholder":46},[33,1469,1470,1472,1474,1476,1478,1480],{"class":35,"line":110},[33,1471,545],{"class":65},[33,1473,1391],{"class":69},[33,1475,74],{"class":73},[33,1477,860],{"class":69},[33,1479,431],{"class":73},[33,1481,694],{"class":65},[33,1483,1484,1486,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506,1508,1510,1512,1514,1516,1518,1520,1522,1524,1526,1528,1531,1533,1535,1537,1539],{"class":35,"line":116},[33,1485,591],{"class":65},[33,1487,1242],{"class":73},[33,1489,1410],{"class":69},[33,1491,80],{"class":73},[33,1493,1415],{"class":86},[33,1495,221],{"class":73},[33,1497,860],{"class":69},[33,1499,74],{"class":73},[33,1501,1410],{"class":69},[33,1503,1291],{"class":73},[33,1505,607],{"class":65},[33,1507,1430],{"class":69},[33,1509,74],{"class":73},[33,1511,1435],{"class":69},[33,1513,80],{"class":73},[33,1515,1440],{"class":86},[33,1517,221],{"class":73},[33,1519,1410],{"class":69},[33,1521,270],{"class":65},[33,1523,1449],{"class":69},[33,1525,236],{"class":73},[33,1527,90],{"class":65},[33,1529,1530],{"class":69}," List",[33,1532,74],{"class":73},[33,1534,1435],{"class":69},[33,1536,431],{"class":73},[33,1538,434],{"class":65},[33,1540,1541],{"class":73}," fa.map(f)\n",[33,1543,1544],{"class":35,"line":122},[33,1545,47],{"emptyLinePlaceholder":46},[33,1547,1548,1550,1552,1554,1557,1559],{"class":35,"line":128},[33,1549,545],{"class":65},[33,1551,1391],{"class":69},[33,1553,74],{"class":73},[33,1555,1556],{"class":69},"Option",[33,1558,431],{"class":73},[33,1560,694],{"class":65},[33,1562,1563,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1610,1612,1614,1616,1618],{"class":35,"line":149},[33,1564,591],{"class":65},[33,1566,1242],{"class":73},[33,1568,1410],{"class":69},[33,1570,80],{"class":73},[33,1572,1415],{"class":86},[33,1574,221],{"class":73},[33,1576,1556],{"class":69},[33,1578,74],{"class":73},[33,1580,1410],{"class":69},[33,1582,1291],{"class":73},[33,1584,607],{"class":65},[33,1586,1430],{"class":69},[33,1588,74],{"class":73},[33,1590,1435],{"class":69},[33,1592,80],{"class":73},[33,1594,1440],{"class":86},[33,1596,221],{"class":73},[33,1598,1410],{"class":69},[33,1600,270],{"class":65},[33,1602,1449],{"class":69},[33,1604,236],{"class":73},[33,1606,90],{"class":65},[33,1608,1609],{"class":69}," Option",[33,1611,74],{"class":73},[33,1613,1435],{"class":69},[33,1615,431],{"class":73},[33,1617,434],{"class":65},[33,1619,1541],{"class":73},[33,1621,1622],{"class":35,"line":155},[33,1623,47],{"emptyLinePlaceholder":46},[33,1625,1626],{"class":35,"line":161},[33,1627,1628],{"class":39},"\u002F\u002F Usage: works on ANY functor, regardless of concrete type\n",[33,1630,1631,1633,1636,1638,1640,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661,1663,1665,1667,1669,1671,1673,1676,1679,1682],{"class":35,"line":166},[33,1632,607],{"class":65},[33,1634,1635],{"class":69}," doubleAll",[33,1637,74],{"class":73},[33,1639,1396],{"class":69},[33,1641,1642],{"class":73},"[_]",[33,1644,90],{"class":65},[33,1646,1391],{"class":69},[33,1648,80],{"class":73},[33,1650,1415],{"class":86},[33,1652,221],{"class":73},[33,1654,1396],{"class":69},[33,1656,74],{"class":73},[33,1658,689],{"class":69},[33,1660,883],{"class":73},[33,1662,90],{"class":65},[33,1664,1456],{"class":69},[33,1666,74],{"class":73},[33,1668,689],{"class":69},[33,1670,431],{"class":73},[33,1672,434],{"class":65},[33,1674,1675],{"class":73}," fa.map(_ ",[33,1677,1678],{"class":65},"*",[33,1680,1681],{"class":920}," 2",[33,1683,96],{"class":73},[33,1685,1686,1689,1691,1693,1695,1697,1699,1701,1703,1705],{"class":35,"line":172},[33,1687,1688],{"class":73},"doubleAll(",[33,1690,860],{"class":69},[33,1692,215],{"class":73},[33,1694,921],{"class":920},[33,1696,226],{"class":73},[33,1698,926],{"class":920},[33,1700,226],{"class":73},[33,1702,931],{"class":920},[33,1704,956],{"class":73},[33,1706,1707],{"class":39},"\u002F\u002F → List(2, 4, 6)\n",[33,1709,1710,1712,1715,1717,1720,1723],{"class":35,"line":178},[33,1711,1688],{"class":73},[33,1713,1714],{"class":69},"Some",[33,1716,215],{"class":73},[33,1718,1719],{"class":920},"42",[33,1721,1722],{"class":73},"))                         ",[33,1724,1725],{"class":39},"\u002F\u002F → Some(84)\n",[33,1727,1728,1730,1733,1736],{"class":35,"line":184},[33,1729,1688],{"class":73},[33,1731,1732],{"class":69},"None",[33,1734,1735],{"class":73},")                             ",[33,1737,1738],{"class":39},"\u002F\u002F → None\n",[33,1740,1741],{"class":35,"line":206},[33,1742,47],{"emptyLinePlaceholder":46},[33,1744,1745],{"class":35,"line":244},[33,1746,1747],{"class":39},"\u002F\u002F Monad: extends Functor with flatMap (sequencing)\n",[33,1749,1750,1752,1755,1757,1759,1762,1765,1767,1769,1771,1773],{"class":35,"line":250},[33,1751,187],{"class":65},[33,1753,1754],{"class":69}," Monad",[33,1756,74],{"class":73},[33,1758,1396],{"class":69},[33,1760,1761],{"class":73},"[_]] ",[33,1763,1764],{"class":65},"extends",[33,1766,1391],{"class":69},[33,1768,74],{"class":73},[33,1770,1396],{"class":69},[33,1772,200],{"class":73},[33,1774,203],{"class":65},[33,1776,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795],{"class":35,"line":256},[33,1778,591],{"class":65},[33,1780,1242],{"class":73},[33,1782,1410],{"class":69},[33,1784,80],{"class":73},[33,1786,1415],{"class":86},[33,1788,221],{"class":73},[33,1790,1396],{"class":69},[33,1792,74],{"class":73},[33,1794,1410],{"class":69},[33,1796,1797],{"class":73},"])\n",[33,1799,1800,1803,1806,1808,1810,1812,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1836],{"class":35,"line":288},[33,1801,1802],{"class":65},"    def",[33,1804,1805],{"class":69}," flatMap",[33,1807,74],{"class":73},[33,1809,1435],{"class":69},[33,1811,80],{"class":73},[33,1813,1440],{"class":86},[33,1815,221],{"class":73},[33,1817,1410],{"class":69},[33,1819,270],{"class":65},[33,1821,1456],{"class":69},[33,1823,74],{"class":73},[33,1825,1435],{"class":69},[33,1827,883],{"class":73},[33,1829,90],{"class":65},[33,1831,1456],{"class":69},[33,1833,74],{"class":73},[33,1835,1435],{"class":69},[33,1837,1463],{"class":73},[33,1839,1840,1842,1844,1846,1848,1850,1852,1854,1856,1858,1860,1862,1864,1866,1868,1870,1872,1874,1877,1879],{"class":35,"line":313},[33,1841,1802],{"class":65},[33,1843,1430],{"class":69},[33,1845,74],{"class":73},[33,1847,1435],{"class":69},[33,1849,80],{"class":73},[33,1851,1440],{"class":86},[33,1853,221],{"class":73},[33,1855,1410],{"class":69},[33,1857,270],{"class":65},[33,1859,1449],{"class":69},[33,1861,236],{"class":73},[33,1863,90],{"class":65},[33,1865,1456],{"class":69},[33,1867,74],{"class":73},[33,1869,1435],{"class":69},[33,1871,431],{"class":73},[33,1873,434],{"class":65},[33,1875,1876],{"class":73}," flatMap(a ",[33,1878,282],{"class":65},[33,1880,1881],{"class":73}," pure(f(a)))\n",[33,1883,1884,1886,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907,1909,1911],{"class":35,"line":318},[33,1885,209],{"class":65},[33,1887,1888],{"class":69}," pure",[33,1890,74],{"class":73},[33,1892,1410],{"class":69},[33,1894,80],{"class":73},[33,1896,218],{"class":86},[33,1898,221],{"class":73},[33,1900,1410],{"class":69},[33,1902,236],{"class":73},[33,1904,90],{"class":65},[33,1906,1456],{"class":69},[33,1908,74],{"class":73},[33,1910,1410],{"class":69},[33,1912,1463],{"class":73},[33,1914,1915],{"class":35,"line":324},[33,1916,47],{"emptyLinePlaceholder":46},[33,1918,1919,1921,1923,1925,1927,1929],{"class":35,"line":330},[33,1920,545],{"class":65},[33,1922,1754],{"class":69},[33,1924,74],{"class":73},[33,1926,1556],{"class":69},[33,1928,431],{"class":73},[33,1930,694],{"class":65},[33,1932,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951],{"class":35,"line":336},[33,1934,591],{"class":65},[33,1936,1242],{"class":73},[33,1938,1410],{"class":69},[33,1940,80],{"class":73},[33,1942,1415],{"class":86},[33,1944,221],{"class":73},[33,1946,1556],{"class":69},[33,1948,74],{"class":73},[33,1950,1410],{"class":69},[33,1952,1797],{"class":73},[33,1954,1955,1957,1959,1961,1963,1965,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991,1993],{"class":35,"line":1014},[33,1956,1802],{"class":65},[33,1958,1805],{"class":69},[33,1960,74],{"class":73},[33,1962,1435],{"class":69},[33,1964,80],{"class":73},[33,1966,1440],{"class":86},[33,1968,221],{"class":73},[33,1970,1410],{"class":69},[33,1972,270],{"class":65},[33,1974,1609],{"class":69},[33,1976,74],{"class":73},[33,1978,1435],{"class":69},[33,1980,883],{"class":73},[33,1982,90],{"class":65},[33,1984,1609],{"class":69},[33,1986,74],{"class":73},[33,1988,1435],{"class":69},[33,1990,431],{"class":73},[33,1992,434],{"class":65},[33,1994,1995],{"class":73}," fa.flatMap(f)\n",[33,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2019,2021,2023,2025,2027,2029,2032],{"class":35,"line":1998},30,[33,2000,209],{"class":65},[33,2002,1888],{"class":69},[33,2004,74],{"class":73},[33,2006,1410],{"class":69},[33,2008,80],{"class":73},[33,2010,218],{"class":86},[33,2012,221],{"class":73},[33,2014,1410],{"class":69},[33,2016,236],{"class":73},[33,2018,90],{"class":65},[33,2020,1609],{"class":69},[33,2022,74],{"class":73},[33,2024,1410],{"class":69},[33,2026,431],{"class":73},[33,2028,434],{"class":65},[33,2030,2031],{"class":69}," Some",[33,2033,2034],{"class":73},"(a)\n",[33,2036,2038],{"class":35,"line":2037},31,[33,2039,47],{"emptyLinePlaceholder":46},[33,2041,2043],{"class":35,"line":2042},32,[33,2044,2045],{"class":39},"\u002F\u002F Generic monadic computation — works for Option, List, Future, IO, etc.\n",[33,2047,2049,2051,2054,2056,2058,2060,2062,2064,2066,2068,2070,2072,2074,2077,2079,2081,2083,2085,2087,2089,2091,2093,2096,2099,2101,2103,2105,2107,2109,2111,2113,2115,2117,2119,2121,2123,2125,2127,2129,2131],{"class":35,"line":2048},33,[33,2050,607],{"class":65},[33,2052,2053],{"class":69}," compose",[33,2055,74],{"class":73},[33,2057,1396],{"class":69},[33,2059,1642],{"class":73},[33,2061,90],{"class":65},[33,2063,1754],{"class":69},[33,2065,226],{"class":73},[33,2067,1410],{"class":69},[33,2069,226],{"class":73},[33,2071,1435],{"class":69},[33,2073,226],{"class":73},[33,2075,2076],{"class":69},"C",[33,2078,80],{"class":73},[33,2080,1440],{"class":86},[33,2082,221],{"class":73},[33,2084,1410],{"class":69},[33,2086,270],{"class":65},[33,2088,1456],{"class":69},[33,2090,74],{"class":73},[33,2092,1435],{"class":69},[33,2094,2095],{"class":73},"], ",[33,2097,2098],{"class":86},"g",[33,2100,221],{"class":73},[33,2102,1435],{"class":69},[33,2104,270],{"class":65},[33,2106,1456],{"class":69},[33,2108,74],{"class":73},[33,2110,2076],{"class":69},[33,2112,867],{"class":73},[33,2114,218],{"class":86},[33,2116,221],{"class":73},[33,2118,1410],{"class":69},[33,2120,236],{"class":73},[33,2122,90],{"class":65},[33,2124,1456],{"class":69},[33,2126,74],{"class":73},[33,2128,2076],{"class":69},[33,2130,431],{"class":73},[33,2132,2133],{"class":65},"=\n",[33,2135,2137,2140],{"class":35,"line":2136},34,[33,2138,2139],{"class":73},"  f(a).flatMap(g)                           ",[33,2141,2142],{"class":39},"\u002F\u002F no knowledge of F's concrete type\n",[15,2144,2146],{"id":2145},"phantom-types-compile-time-state-machines","Phantom Types — Compile-Time State Machines",[20,2148,2149],{"language":22},[24,2150,2152],{"className":26,"code":2151,"language":22,"meta":28,"style":28},"\u002F\u002F Phantom types: type parameters that exist only at compile time, erased at runtime.\n\u002F\u002F Used to encode state transitions in the type system — invalid transitions don't compile.\n\nsealed trait ConnectionState\nobject ConnectionState:\n  trait Disconnected extends ConnectionState\n  trait Connecting extends ConnectionState\n  trait Connected extends ConnectionState\n  trait Closed extends ConnectionState\n\n\u002F\u002F The type parameter [S] is phantom — it never appears in fields.\n\u002F\u002F It exists ONLY to track state at compile time.\nfinal class Connection[S \u003C: ConnectionState] private (val host: String, val port: Int):\n  \u002F\u002F State transitions encoded in return types\n  def connect()(using S \u003C:\u003C ConnectionState.Disconnected): Connection[ConnectionState.Connecting] =\n    new Connection[ConnectionState.Connecting](host, port)  \u002F\u002F runtime: same object, new phantom type\n\n  def waitForConnection()(using S \u003C:\u003C ConnectionState.Connecting): Connection[ConnectionState.Connected] =\n    new Connection[ConnectionState.Connected](host, port)\n\n  def disconnect()(using S \u003C:\u003C ConnectionState.Connected): Connection[ConnectionState.Disconnected] =\n    new Connection[ConnectionState.Disconnected](host, port)\n\n  def close()(using S \u003C:\u003C ConnectionState.Disconnected): Connection[ConnectionState.Closed] =\n    new Connection[ConnectionState.Closed](host, port)\n\nobject Connection:\n  def create(host: String, port: Int): Connection[ConnectionState.Disconnected] =\n    new Connection[ConnectionState.Disconnected](host, port)\n\n\u002F\u002F Usage — invalid transitions DON'T COMPILE:\nval conn = Connection.create(\"api.x.com\", 443)  \u002F\u002F Connection[Disconnected]\n\u002F\u002F conn.disconnect()  \u002F\u002F ERROR: not in Connected state\nval connecting = conn.connect()                   \u002F\u002F Connection[Connecting]\n\u002F\u002F connecting.connect()  \u002F\u002F ERROR: not in Disconnected state\nval connected = connecting.waitForConnection()    \u002F\u002F Connection[Connected]\nval disconnected = connected.disconnect()         \u002F\u002F Connection[Disconnected]\nval closed = disconnected.close()                 \u002F\u002F Connection[Closed]\n\u002F\u002F closed.connect()  \u002F\u002F ERROR: not in Disconnected state (it's Closed)\n\n\u002F\u002F Runtime cost: ZERO. The type parameter [S] is erased — no field stores it.\n\u002F\u002F The `\u003C:\u003C` evidence parameter is a `null` at runtime (optimized away by the compiler).\n",[30,2153,2154,2159,2164,2168,2179,2188,2201,2212,2223,2234,2238,2243,2248,2301,2306,2352,2373,2377,2417,2434,2438,2477,2493,2497,2537,2553,2557,2565,2608,2624,2628,2633,2661,2669,2684,2693,2709,2724,2740,2749,2754,2760],{"__ignoreMap":28},[33,2155,2156],{"class":35,"line":36},[33,2157,2158],{"class":39},"\u002F\u002F Phantom types: type parameters that exist only at compile time, erased at runtime.\n",[33,2160,2161],{"class":35,"line":43},[33,2162,2163],{"class":39},"\u002F\u002F Used to encode state transitions in the type system — invalid transitions don't compile.\n",[33,2165,2166],{"class":35,"line":50},[33,2167,47],{"emptyLinePlaceholder":46},[33,2169,2170,2173,2176],{"class":35,"line":56},[33,2171,2172],{"class":65},"sealed",[33,2174,2175],{"class":65}," trait",[33,2177,2178],{"class":69}," ConnectionState\n",[33,2180,2181,2183,2186],{"class":35,"line":62},[33,2182,1160],{"class":65},[33,2184,2185],{"class":69}," ConnectionState",[33,2187,203],{"class":65},[33,2189,2190,2193,2196,2199],{"class":35,"line":99},[33,2191,2192],{"class":65},"  trait",[33,2194,2195],{"class":69}," Disconnected",[33,2197,2198],{"class":65}," extends",[33,2200,2178],{"class":69},[33,2202,2203,2205,2208,2210],{"class":35,"line":105},[33,2204,2192],{"class":65},[33,2206,2207],{"class":69}," Connecting",[33,2209,2198],{"class":65},[33,2211,2178],{"class":69},[33,2213,2214,2216,2219,2221],{"class":35,"line":110},[33,2215,2192],{"class":65},[33,2217,2218],{"class":69}," Connected",[33,2220,2198],{"class":65},[33,2222,2178],{"class":69},[33,2224,2225,2227,2230,2232],{"class":35,"line":116},[33,2226,2192],{"class":65},[33,2228,2229],{"class":69}," Closed",[33,2231,2198],{"class":65},[33,2233,2178],{"class":69},[33,2235,2236],{"class":35,"line":122},[33,2237,47],{"emptyLinePlaceholder":46},[33,2239,2240],{"class":35,"line":128},[33,2241,2242],{"class":39},"\u002F\u002F The type parameter [S] is phantom — it never appears in fields.\n",[33,2244,2245],{"class":35,"line":149},[33,2246,2247],{"class":39},"\u002F\u002F It exists ONLY to track state at compile time.\n",[33,2249,2250,2253,2256,2259,2261,2264,2267,2269,2271,2274,2276,2278,2281,2283,2285,2287,2289,2292,2294,2297,2299],{"class":35,"line":155},[33,2251,2252],{"class":65},"final",[33,2254,2255],{"class":65}," class",[33,2257,2258],{"class":69}," Connection",[33,2260,74],{"class":73},[33,2262,2263],{"class":69},"S",[33,2265,2266],{"class":65}," \u003C:",[33,2268,2185],{"class":69},[33,2270,431],{"class":73},[33,2272,2273],{"class":65},"private",[33,2275,594],{"class":73},[33,2277,259],{"class":65},[33,2279,2280],{"class":86}," host",[33,2282,90],{"class":65},[33,2284,273],{"class":69},[33,2286,226],{"class":73},[33,2288,259],{"class":65},[33,2290,2291],{"class":86}," port",[33,2293,90],{"class":65},[33,2295,2296],{"class":69}," Int",[33,2298,236],{"class":73},[33,2300,203],{"class":65},[33,2302,2303],{"class":35,"line":161},[33,2304,2305],{"class":39},"  \u002F\u002F State transitions encoded in return types\n",[33,2307,2308,2310,2313,2316,2318,2321,2324,2326,2329,2332,2334,2336,2338,2340,2343,2345,2348,2350],{"class":35,"line":166},[33,2309,209],{"class":65},[33,2311,2312],{"class":69}," connect",[33,2314,2315],{"class":73},"()(",[33,2317,549],{"class":65},[33,2319,2320],{"class":69}," S",[33,2322,2323],{"class":65}," \u003C:\u003C",[33,2325,2185],{"class":69},[33,2327,2328],{"class":73},".",[33,2330,2331],{"class":69},"Disconnected",[33,2333,236],{"class":73},[33,2335,90],{"class":65},[33,2337,2258],{"class":69},[33,2339,74],{"class":73},[33,2341,2342],{"class":69},"ConnectionState",[33,2344,2328],{"class":73},[33,2346,2347],{"class":69},"Connecting",[33,2349,431],{"class":73},[33,2351,2133],{"class":65},[33,2353,2354,2357,2359,2361,2363,2365,2367,2370],{"class":35,"line":172},[33,2355,2356],{"class":65},"    new",[33,2358,2258],{"class":69},[33,2360,74],{"class":73},[33,2362,2342],{"class":69},[33,2364,2328],{"class":73},[33,2366,2347],{"class":69},[33,2368,2369],{"class":73},"](host, port)  ",[33,2371,2372],{"class":39},"\u002F\u002F runtime: same object, new phantom type\n",[33,2374,2375],{"class":35,"line":178},[33,2376,47],{"emptyLinePlaceholder":46},[33,2378,2379,2381,2384,2386,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410,2413,2415],{"class":35,"line":184},[33,2380,209],{"class":65},[33,2382,2383],{"class":69}," waitForConnection",[33,2385,2315],{"class":73},[33,2387,549],{"class":65},[33,2389,2320],{"class":69},[33,2391,2323],{"class":65},[33,2393,2185],{"class":69},[33,2395,2328],{"class":73},[33,2397,2347],{"class":69},[33,2399,236],{"class":73},[33,2401,90],{"class":65},[33,2403,2258],{"class":69},[33,2405,74],{"class":73},[33,2407,2342],{"class":69},[33,2409,2328],{"class":73},[33,2411,2412],{"class":69},"Connected",[33,2414,431],{"class":73},[33,2416,2133],{"class":65},[33,2418,2419,2421,2423,2425,2427,2429,2431],{"class":35,"line":206},[33,2420,2356],{"class":65},[33,2422,2258],{"class":69},[33,2424,74],{"class":73},[33,2426,2342],{"class":69},[33,2428,2328],{"class":73},[33,2430,2412],{"class":69},[33,2432,2433],{"class":73},"](host, port)\n",[33,2435,2436],{"class":35,"line":244},[33,2437,47],{"emptyLinePlaceholder":46},[33,2439,2440,2442,2445,2447,2449,2451,2453,2455,2457,2459,2461,2463,2465,2467,2469,2471,2473,2475],{"class":35,"line":250},[33,2441,209],{"class":65},[33,2443,2444],{"class":69}," disconnect",[33,2446,2315],{"class":73},[33,2448,549],{"class":65},[33,2450,2320],{"class":69},[33,2452,2323],{"class":65},[33,2454,2185],{"class":69},[33,2456,2328],{"class":73},[33,2458,2412],{"class":69},[33,2460,236],{"class":73},[33,2462,90],{"class":65},[33,2464,2258],{"class":69},[33,2466,74],{"class":73},[33,2468,2342],{"class":69},[33,2470,2328],{"class":73},[33,2472,2331],{"class":69},[33,2474,431],{"class":73},[33,2476,2133],{"class":65},[33,2478,2479,2481,2483,2485,2487,2489,2491],{"class":35,"line":256},[33,2480,2356],{"class":65},[33,2482,2258],{"class":69},[33,2484,74],{"class":73},[33,2486,2342],{"class":69},[33,2488,2328],{"class":73},[33,2490,2331],{"class":69},[33,2492,2433],{"class":73},[33,2494,2495],{"class":35,"line":288},[33,2496,47],{"emptyLinePlaceholder":46},[33,2498,2499,2501,2504,2506,2508,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530,2533,2535],{"class":35,"line":313},[33,2500,209],{"class":65},[33,2502,2503],{"class":69}," close",[33,2505,2315],{"class":73},[33,2507,549],{"class":65},[33,2509,2320],{"class":69},[33,2511,2323],{"class":65},[33,2513,2185],{"class":69},[33,2515,2328],{"class":73},[33,2517,2331],{"class":69},[33,2519,236],{"class":73},[33,2521,90],{"class":65},[33,2523,2258],{"class":69},[33,2525,74],{"class":73},[33,2527,2342],{"class":69},[33,2529,2328],{"class":73},[33,2531,2532],{"class":69},"Closed",[33,2534,431],{"class":73},[33,2536,2133],{"class":65},[33,2538,2539,2541,2543,2545,2547,2549,2551],{"class":35,"line":318},[33,2540,2356],{"class":65},[33,2542,2258],{"class":69},[33,2544,74],{"class":73},[33,2546,2342],{"class":69},[33,2548,2328],{"class":73},[33,2550,2532],{"class":69},[33,2552,2433],{"class":73},[33,2554,2555],{"class":35,"line":324},[33,2556,47],{"emptyLinePlaceholder":46},[33,2558,2559,2561,2563],{"class":35,"line":330},[33,2560,1160],{"class":65},[33,2562,2258],{"class":69},[33,2564,203],{"class":65},[33,2566,2567,2569,2572,2574,2577,2579,2581,2583,2586,2588,2590,2592,2594,2596,2598,2600,2602,2604,2606],{"class":35,"line":336},[33,2568,209],{"class":65},[33,2570,2571],{"class":69}," create",[33,2573,215],{"class":73},[33,2575,2576],{"class":86},"host",[33,2578,221],{"class":73},[33,2580,746],{"class":69},[33,2582,226],{"class":73},[33,2584,2585],{"class":86},"port",[33,2587,221],{"class":73},[33,2589,689],{"class":69},[33,2591,236],{"class":73},[33,2593,90],{"class":65},[33,2595,2258],{"class":69},[33,2597,74],{"class":73},[33,2599,2342],{"class":69},[33,2601,2328],{"class":73},[33,2603,2331],{"class":69},[33,2605,431],{"class":73},[33,2607,2133],{"class":65},[33,2609,2610,2612,2614,2616,2618,2620,2622],{"class":35,"line":1014},[33,2611,2356],{"class":65},[33,2613,2258],{"class":69},[33,2615,74],{"class":73},[33,2617,2342],{"class":69},[33,2619,2328],{"class":73},[33,2621,2331],{"class":69},[33,2623,2433],{"class":73},[33,2625,2626],{"class":35,"line":1998},[33,2627,47],{"emptyLinePlaceholder":46},[33,2629,2630],{"class":35,"line":2037},[33,2631,2632],{"class":39},"\u002F\u002F Usage — invalid transitions DON'T COMPILE:\n",[33,2634,2635,2637,2640,2642,2644,2647,2650,2652,2655,2658],{"class":35,"line":2042},[33,2636,259],{"class":65},[33,2638,2639],{"class":86}," conn",[33,2641,276],{"class":65},[33,2643,2258],{"class":69},[33,2645,2646],{"class":73},".create(",[33,2648,2649],{"class":724},"\"api.x.com\"",[33,2651,226],{"class":73},[33,2653,2654],{"class":920},"443",[33,2656,2657],{"class":73},")  ",[33,2659,2660],{"class":39},"\u002F\u002F Connection[Disconnected]\n",[33,2662,2663,2666],{"class":35,"line":2048},[33,2664,2665],{"class":39},"\u002F\u002F conn.disconnect()",[33,2667,2668],{"class":39},"  \u002F\u002F ERROR: not in Connected state\n",[33,2670,2671,2673,2676,2678,2681],{"class":35,"line":2136},[33,2672,259],{"class":65},[33,2674,2675],{"class":86}," connecting",[33,2677,276],{"class":65},[33,2679,2680],{"class":73}," conn.connect()                   ",[33,2682,2683],{"class":39},"\u002F\u002F Connection[Connecting]\n",[33,2685,2687,2690],{"class":35,"line":2686},35,[33,2688,2689],{"class":39},"\u002F\u002F connecting.connect()",[33,2691,2692],{"class":39},"  \u002F\u002F ERROR: not in Disconnected state\n",[33,2694,2696,2698,2701,2703,2706],{"class":35,"line":2695},36,[33,2697,259],{"class":65},[33,2699,2700],{"class":86}," connected",[33,2702,276],{"class":65},[33,2704,2705],{"class":73}," connecting.waitForConnection()    ",[33,2707,2708],{"class":39},"\u002F\u002F Connection[Connected]\n",[33,2710,2712,2714,2717,2719,2722],{"class":35,"line":2711},37,[33,2713,259],{"class":65},[33,2715,2716],{"class":86}," disconnected",[33,2718,276],{"class":65},[33,2720,2721],{"class":73}," connected.disconnect()         ",[33,2723,2660],{"class":39},[33,2725,2727,2729,2732,2734,2737],{"class":35,"line":2726},38,[33,2728,259],{"class":65},[33,2730,2731],{"class":86}," closed",[33,2733,276],{"class":65},[33,2735,2736],{"class":73}," disconnected.close()                 ",[33,2738,2739],{"class":39},"\u002F\u002F Connection[Closed]\n",[33,2741,2743,2746],{"class":35,"line":2742},39,[33,2744,2745],{"class":39},"\u002F\u002F closed.connect()",[33,2747,2748],{"class":39},"  \u002F\u002F ERROR: not in Disconnected state (it's Closed)\n",[33,2750,2752],{"class":35,"line":2751},40,[33,2753,47],{"emptyLinePlaceholder":46},[33,2755,2757],{"class":35,"line":2756},41,[33,2758,2759],{"class":39},"\u002F\u002F Runtime cost: ZERO. The type parameter [S] is erased — no field stores it.\n",[33,2761,2763],{"class":35,"line":2762},42,[33,2764,2765],{"class":39},"\u002F\u002F The `\u003C:\u003C` evidence parameter is a `null` at runtime (optimized away by the compiler).\n",[15,2767,2769],{"id":2768},"opaque-types-zero-cost-type-aliases","Opaque Types — Zero-Cost Type Aliases",[20,2771,2772],{"language":22},[24,2773,2775],{"className":26,"code":2774,"language":22,"meta":28,"style":28},"\u002F\u002F opaque type: a type alias that's ONLY visible inside its defining object.\n\u002F\u002F Outside the object, it's a distinct type — the compiler prevents mixing it with the underlying type.\n\nobject AccountId:\n  opaque type AccountId = Long              \u002F\u002F outside: AccountId is its own type\n  def apply(l: Long): AccountId = l         \u002F\u002F smart constructor\n  extension (id: AccountId) def value: Long = id  \u002F\u002F accessor (only works if in scope)\n\nobject UserId:\n  opaque type UserId = Long\n  def apply(l: Long): UserId = l\n  extension (id: UserId) def value: Long = id\n\n\u002F\u002F At runtime: AccountId and UserId are both just `long` — zero overhead.\n\u002F\u002F At compile time: they're distinct types.\nval acct: AccountId = AccountId(42)\nval user: UserId = UserId(42)\n\u002F\u002F acct == user  \u002F\u002F COMPILE ERROR: different types, even though both are Long at runtime\n\u002F\u002F acct + 1      \u002F\u002F COMPILE ERROR: AccountId has no + method (no extension defined)\n\n\u002F\u002F This replaces value classes (AnyVal) for primitive wrappers — no boxing, no wrapper object.\n",[30,2776,2777,2782,2787,2791,2800,2818,2849,2881,2885,2894,2907,2932,2960,2964,2969,2974,2995,3016,3024,3032,3036],{"__ignoreMap":28},[33,2778,2779],{"class":35,"line":36},[33,2780,2781],{"class":39},"\u002F\u002F opaque type: a type alias that's ONLY visible inside its defining object.\n",[33,2783,2784],{"class":35,"line":43},[33,2785,2786],{"class":39},"\u002F\u002F Outside the object, it's a distinct type — the compiler prevents mixing it with the underlying type.\n",[33,2788,2789],{"class":35,"line":50},[33,2790,47],{"emptyLinePlaceholder":46},[33,2792,2793,2795,2798],{"class":35,"line":56},[33,2794,1160],{"class":65},[33,2796,2797],{"class":69}," AccountId",[33,2799,203],{"class":65},[33,2801,2802,2805,2808,2810,2812,2815],{"class":35,"line":62},[33,2803,2804],{"class":65},"  opaque",[33,2806,2807],{"class":65}," type",[33,2809,2797],{"class":69},[33,2811,276],{"class":65},[33,2813,2814],{"class":69}," Long",[33,2816,2817],{"class":39},"              \u002F\u002F outside: AccountId is its own type\n",[33,2819,2820,2822,2825,2827,2830,2832,2835,2837,2839,2841,2843,2846],{"class":35,"line":99},[33,2821,209],{"class":65},[33,2823,2824],{"class":69}," apply",[33,2826,215],{"class":73},[33,2828,2829],{"class":86},"l",[33,2831,221],{"class":73},[33,2833,2834],{"class":69},"Long",[33,2836,236],{"class":73},[33,2838,90],{"class":65},[33,2840,2797],{"class":69},[33,2842,276],{"class":65},[33,2844,2845],{"class":73}," l         ",[33,2847,2848],{"class":39},"\u002F\u002F smart constructor\n",[33,2850,2851,2853,2855,2858,2860,2863,2865,2867,2869,2871,2873,2875,2878],{"class":35,"line":105},[33,2852,591],{"class":65},[33,2854,594],{"class":73},[33,2856,2857],{"class":86},"id",[33,2859,221],{"class":73},[33,2861,2862],{"class":69},"AccountId",[33,2864,604],{"class":73},[33,2866,607],{"class":65},[33,2868,87],{"class":69},[33,2870,90],{"class":65},[33,2872,2814],{"class":69},[33,2874,276],{"class":65},[33,2876,2877],{"class":73}," id  ",[33,2879,2880],{"class":39},"\u002F\u002F accessor (only works if in scope)\n",[33,2882,2883],{"class":35,"line":110},[33,2884,47],{"emptyLinePlaceholder":46},[33,2886,2887,2889,2892],{"class":35,"line":116},[33,2888,1160],{"class":65},[33,2890,2891],{"class":69}," UserId",[33,2893,203],{"class":65},[33,2895,2896,2898,2900,2902,2904],{"class":35,"line":122},[33,2897,2804],{"class":65},[33,2899,2807],{"class":65},[33,2901,2891],{"class":69},[33,2903,276],{"class":65},[33,2905,2906],{"class":69}," Long\n",[33,2908,2909,2911,2913,2915,2917,2919,2921,2923,2925,2927,2929],{"class":35,"line":128},[33,2910,209],{"class":65},[33,2912,2824],{"class":69},[33,2914,215],{"class":73},[33,2916,2829],{"class":86},[33,2918,221],{"class":73},[33,2920,2834],{"class":69},[33,2922,236],{"class":73},[33,2924,90],{"class":65},[33,2926,2891],{"class":69},[33,2928,276],{"class":65},[33,2930,2931],{"class":73}," l\n",[33,2933,2934,2936,2938,2940,2942,2945,2947,2949,2951,2953,2955,2957],{"class":35,"line":149},[33,2935,591],{"class":65},[33,2937,594],{"class":73},[33,2939,2857],{"class":86},[33,2941,221],{"class":73},[33,2943,2944],{"class":69},"UserId",[33,2946,604],{"class":73},[33,2948,607],{"class":65},[33,2950,87],{"class":69},[33,2952,90],{"class":65},[33,2954,2814],{"class":69},[33,2956,276],{"class":65},[33,2958,2959],{"class":73}," id\n",[33,2961,2962],{"class":35,"line":155},[33,2963,47],{"emptyLinePlaceholder":46},[33,2965,2966],{"class":35,"line":161},[33,2967,2968],{"class":39},"\u002F\u002F At runtime: AccountId and UserId are both just `long` — zero overhead.\n",[33,2970,2971],{"class":35,"line":166},[33,2972,2973],{"class":39},"\u002F\u002F At compile time: they're distinct types.\n",[33,2975,2976,2978,2981,2983,2985,2987,2989,2991,2993],{"class":35,"line":172},[33,2977,259],{"class":65},[33,2979,2980],{"class":86}," acct",[33,2982,90],{"class":65},[33,2984,2797],{"class":69},[33,2986,276],{"class":65},[33,2988,2797],{"class":69},[33,2990,215],{"class":73},[33,2992,1719],{"class":920},[33,2994,96],{"class":73},[33,2996,2997,2999,3002,3004,3006,3008,3010,3012,3014],{"class":35,"line":178},[33,2998,259],{"class":65},[33,3000,3001],{"class":86}," user",[33,3003,90],{"class":65},[33,3005,2891],{"class":69},[33,3007,276],{"class":65},[33,3009,2891],{"class":69},[33,3011,215],{"class":73},[33,3013,1719],{"class":920},[33,3015,96],{"class":73},[33,3017,3018,3021],{"class":35,"line":184},[33,3019,3020],{"class":39},"\u002F\u002F acct == user",[33,3022,3023],{"class":39},"  \u002F\u002F COMPILE ERROR: different types, even though both are Long at runtime\n",[33,3025,3026,3029],{"class":35,"line":206},[33,3027,3028],{"class":39},"\u002F\u002F acct + 1",[33,3030,3031],{"class":39},"      \u002F\u002F COMPILE ERROR: AccountId has no + method (no extension defined)\n",[33,3033,3034],{"class":35,"line":244},[33,3035,47],{"emptyLinePlaceholder":46},[33,3037,3038],{"class":35,"line":250},[33,3039,3040],{"class":39},"\u002F\u002F This replaces value classes (AnyVal) for primitive wrappers — no boxing, no wrapper object.\n",[15,3042,3044],{"id":3043},"match-types-compile-time-type-level-computation","Match Types — Compile-Time Type-Level Computation",[20,3046,3047],{"language":22},[24,3048,3050],{"className":26,"code":3049,"language":22,"meta":28,"style":28},"\u002F\u002F Match types: pattern match on types at the TYPE level, evaluated by the compiler.\n\u002F\u002F This is type-level programming — the \"result\" is a type, computed at compile time.\n\n\u002F\u002F Type-level boolean\ntype Bool = true | false\ntype Not[B \u003C: Boolean] = B match\n  case true  => false\n  case false => true\n\u002F\u002F Not[true] → false (computed by compiler, not runtime)\n\n\u002F\u002F Type-level list operations\ntype Size[T \u003C: Tuple] \u003C: Int = T match\n  case EmptyTuple => 0\n  case _ *: tail => 1 + Size[tail]          \u002F\u002F recursive match type\n\nsummon[Size[(Int, String, Boolean)] =:= 3]  \u002F\u002F compiles: compiler computed 3\n\n\u002F\u002F Type-level serialization — choose a representation per type\ntype WireFormat[T] = T match\n  case Int       => Int\n  case Long      => Long\n  case String    => String\n  case Boolean   => Boolean\n  case Option[t] => Option[WireFormat[t]]\n  case List[t]   => Array[WireFormat[t]]    \u002F\u002F List[Int] → Array[Int] (no boxing!)\n\n\u002F\u002F The compiler reduces WireFormat[List[Option[Int]]] to Array[Option[Int]]\n\u002F\u002F This is how libraries like Magnolia derive type classes generically.\n",[30,3051,3052,3057,3062,3066,3071,3090,3115,3127,3139,3144,3148,3153,3182,3194,3223,3227,3263,3267,3272,3291,3302,3313,3324,3335,3356,3380,3384,3389],{"__ignoreMap":28},[33,3053,3054],{"class":35,"line":36},[33,3055,3056],{"class":39},"\u002F\u002F Match types: pattern match on types at the TYPE level, evaluated by the compiler.\n",[33,3058,3059],{"class":35,"line":43},[33,3060,3061],{"class":39},"\u002F\u002F This is type-level programming — the \"result\" is a type, computed at compile time.\n",[33,3063,3064],{"class":35,"line":50},[33,3065,47],{"emptyLinePlaceholder":46},[33,3067,3068],{"class":35,"line":56},[33,3069,3070],{"class":39},"\u002F\u002F Type-level boolean\n",[33,3072,3073,3076,3079,3081,3084,3087],{"class":35,"line":62},[33,3074,3075],{"class":65},"type",[33,3077,3078],{"class":69}," Bool",[33,3080,276],{"class":65},[33,3082,3083],{"class":920}," true",[33,3085,3086],{"class":65}," |",[33,3088,3089],{"class":920}," false\n",[33,3091,3092,3094,3097,3099,3101,3103,3106,3108,3110,3112],{"class":35,"line":99},[33,3093,3075],{"class":65},[33,3095,3096],{"class":69}," Not",[33,3098,74],{"class":73},[33,3100,1435],{"class":69},[33,3102,2266],{"class":65},[33,3104,3105],{"class":69}," Boolean",[33,3107,431],{"class":73},[33,3109,434],{"class":65},[33,3111,1449],{"class":69},[33,3113,3114],{"class":65}," match\n",[33,3116,3117,3120,3122,3125],{"class":35,"line":105},[33,3118,3119],{"class":65},"  case",[33,3121,3083],{"class":920},[33,3123,3124],{"class":65},"  =>",[33,3126,3089],{"class":920},[33,3128,3129,3131,3134,3136],{"class":35,"line":110},[33,3130,3119],{"class":65},[33,3132,3133],{"class":920}," false",[33,3135,270],{"class":65},[33,3137,3138],{"class":920}," true\n",[33,3140,3141],{"class":35,"line":116},[33,3142,3143],{"class":39},"\u002F\u002F Not[true] → false (computed by compiler, not runtime)\n",[33,3145,3146],{"class":35,"line":122},[33,3147,47],{"emptyLinePlaceholder":46},[33,3149,3150],{"class":35,"line":128},[33,3151,3152],{"class":39},"\u002F\u002F Type-level list operations\n",[33,3154,3155,3157,3160,3162,3164,3166,3169,3171,3174,3176,3178,3180],{"class":35,"line":149},[33,3156,3075],{"class":65},[33,3158,3159],{"class":69}," Size",[33,3161,74],{"class":73},[33,3163,77],{"class":69},[33,3165,2266],{"class":65},[33,3167,3168],{"class":69}," Tuple",[33,3170,431],{"class":73},[33,3172,3173],{"class":65},"\u003C:",[33,3175,2296],{"class":69},[33,3177,276],{"class":65},[33,3179,93],{"class":69},[33,3181,3114],{"class":65},[33,3183,3184,3186,3189,3191],{"class":35,"line":155},[33,3185,3119],{"class":65},[33,3187,3188],{"class":69}," EmptyTuple",[33,3190,270],{"class":65},[33,3192,3193],{"class":920}," 0\n",[33,3195,3196,3198,3201,3204,3207,3209,3212,3215,3217,3220],{"class":35,"line":161},[33,3197,3119],{"class":65},[33,3199,3200],{"class":73}," _ ",[33,3202,3203],{"class":65},"*:",[33,3205,3206],{"class":73}," tail ",[33,3208,282],{"class":65},[33,3210,3211],{"class":920}," 1",[33,3213,3214],{"class":65}," +",[33,3216,3159],{"class":69},[33,3218,3219],{"class":73},"[tail]          ",[33,3221,3222],{"class":39},"\u002F\u002F recursive match type\n",[33,3224,3225],{"class":35,"line":166},[33,3226,47],{"emptyLinePlaceholder":46},[33,3228,3229,3232,3235,3238,3240,3242,3244,3246,3248,3251,3254,3257,3260],{"class":35,"line":172},[33,3230,3231],{"class":73},"summon[",[33,3233,3234],{"class":69},"Size",[33,3236,3237],{"class":73},"[(",[33,3239,689],{"class":69},[33,3241,226],{"class":73},[33,3243,746],{"class":69},[33,3245,226],{"class":73},[33,3247,799],{"class":69},[33,3249,3250],{"class":73},")] ",[33,3252,3253],{"class":65},"=:=",[33,3255,3256],{"class":920}," 3",[33,3258,3259],{"class":73},"]  ",[33,3261,3262],{"class":39},"\u002F\u002F compiles: compiler computed 3\n",[33,3264,3265],{"class":35,"line":178},[33,3266,47],{"emptyLinePlaceholder":46},[33,3268,3269],{"class":35,"line":184},[33,3270,3271],{"class":39},"\u002F\u002F Type-level serialization — choose a representation per type\n",[33,3273,3274,3276,3279,3281,3283,3285,3287,3289],{"class":35,"line":206},[33,3275,3075],{"class":65},[33,3277,3278],{"class":69}," WireFormat",[33,3280,74],{"class":73},[33,3282,77],{"class":69},[33,3284,431],{"class":73},[33,3286,434],{"class":65},[33,3288,93],{"class":69},[33,3290,3114],{"class":65},[33,3292,3293,3295,3297,3300],{"class":35,"line":244},[33,3294,3119],{"class":65},[33,3296,2296],{"class":69},[33,3298,3299],{"class":65},"       =>",[33,3301,241],{"class":69},[33,3303,3304,3306,3308,3311],{"class":35,"line":250},[33,3305,3119],{"class":65},[33,3307,2814],{"class":69},[33,3309,3310],{"class":65},"      =>",[33,3312,2906],{"class":69},[33,3314,3315,3317,3319,3322],{"class":35,"line":256},[33,3316,3119],{"class":65},[33,3318,273],{"class":69},[33,3320,3321],{"class":65},"    =>",[33,3323,615],{"class":69},[33,3325,3326,3328,3330,3333],{"class":35,"line":288},[33,3327,3119],{"class":65},[33,3329,3105],{"class":69},[33,3331,3332],{"class":65},"   =>",[33,3334,669],{"class":69},[33,3336,3337,3339,3341,3344,3346,3348,3350,3353],{"class":35,"line":313},[33,3338,3119],{"class":65},[33,3340,1609],{"class":69},[33,3342,3343],{"class":73},"[t] ",[33,3345,282],{"class":65},[33,3347,1609],{"class":69},[33,3349,74],{"class":73},[33,3351,3352],{"class":69},"WireFormat",[33,3354,3355],{"class":73},"[t]]\n",[33,3357,3358,3360,3362,3365,3367,3370,3372,3374,3377],{"class":35,"line":318},[33,3359,3119],{"class":65},[33,3361,1530],{"class":69},[33,3363,3364],{"class":73},"[t]   ",[33,3366,282],{"class":65},[33,3368,3369],{"class":69}," Array",[33,3371,74],{"class":73},[33,3373,3352],{"class":69},[33,3375,3376],{"class":73},"[t]]    ",[33,3378,3379],{"class":39},"\u002F\u002F List[Int] → Array[Int] (no boxing!)\n",[33,3381,3382],{"class":35,"line":324},[33,3383,47],{"emptyLinePlaceholder":46},[33,3385,3386],{"class":35,"line":330},[33,3387,3388],{"class":39},"\u002F\u002F The compiler reduces WireFormat[List[Option[Int]]] to Array[Option[Int]]\n",[33,3390,3391],{"class":35,"line":336},[33,3392,3393],{"class":39},"\u002F\u002F This is how libraries like Magnolia derive type classes generically.\n",[15,3395,3397],{"id":3396},"type-projections-dependent-types","Type Projections & Dependent Types",[20,3399,3400],{"language":22},[24,3401,3403],{"className":26,"code":3402,"language":22,"meta":28,"style":28},"\u002F\u002F Path-dependent type: a type that depends on a value (instance)\nclass Repository:\n  type Entity                            \u002F\u002F abstract type member\n  def get(id: Long): Option[Entity]\n  def save(e: Entity): Long\n\nclass UserRepo extends Repository:\n  type Entity = User                     \u002F\u002F concrete: Entity is User\n  def get(id: Long): Option[User] = ???\n  def save(e: User): Long = ???\n\nclass OrderRepo extends Repository:\n  type Entity = Order                    \u002F\u002F concrete: Entity is Order\n  def get(id: Long): Option[Order] = ???\n  def save(e: Order): Long = ???\n\n\u002F\u002F The type repo.Entity depends on which repo instance you use\ndef transfer(from: Repository, to: Repository)(e: from.Entity): to.Entity = ???\n\u002F\u002F from.Entity and to.Entity are different types — can't mix them.\n\u002F\u002F This prevents passing a User to an OrderRepo — type-safe at compile time.\n",[30,3404,3405,3410,3419,3430,3458,3480,3484,3497,3511,3543,3567,3571,3584,3598,3629,3653,3657,3662,3711,3716],{"__ignoreMap":28},[33,3406,3407],{"class":35,"line":36},[33,3408,3409],{"class":39},"\u002F\u002F Path-dependent type: a type that depends on a value (instance)\n",[33,3411,3412,3414,3417],{"class":35,"line":43},[33,3413,66],{"class":65},[33,3415,3416],{"class":69}," Repository",[33,3418,203],{"class":65},[33,3420,3421,3424,3427],{"class":35,"line":50},[33,3422,3423],{"class":65},"  type",[33,3425,3426],{"class":69}," Entity",[33,3428,3429],{"class":39},"                            \u002F\u002F abstract type member\n",[33,3431,3432,3434,3437,3439,3441,3443,3445,3447,3449,3451,3453,3456],{"class":35,"line":56},[33,3433,209],{"class":65},[33,3435,3436],{"class":69}," get",[33,3438,215],{"class":73},[33,3440,2857],{"class":86},[33,3442,221],{"class":73},[33,3444,2834],{"class":69},[33,3446,236],{"class":73},[33,3448,90],{"class":65},[33,3450,1609],{"class":69},[33,3452,74],{"class":73},[33,3454,3455],{"class":69},"Entity",[33,3457,1463],{"class":73},[33,3459,3460,3462,3465,3467,3470,3472,3474,3476,3478],{"class":35,"line":62},[33,3461,209],{"class":65},[33,3463,3464],{"class":69}," save",[33,3466,215],{"class":73},[33,3468,3469],{"class":86},"e",[33,3471,221],{"class":73},[33,3473,3455],{"class":69},[33,3475,236],{"class":73},[33,3477,90],{"class":65},[33,3479,2906],{"class":69},[33,3481,3482],{"class":35,"line":99},[33,3483,47],{"emptyLinePlaceholder":46},[33,3485,3486,3488,3491,3493,3495],{"class":35,"line":105},[33,3487,66],{"class":65},[33,3489,3490],{"class":69}," UserRepo",[33,3492,2198],{"class":65},[33,3494,3416],{"class":69},[33,3496,203],{"class":65},[33,3498,3499,3501,3503,3505,3508],{"class":35,"line":110},[33,3500,3423],{"class":65},[33,3502,3426],{"class":69},[33,3504,276],{"class":65},[33,3506,3507],{"class":69}," User",[33,3509,3510],{"class":39},"                     \u002F\u002F concrete: Entity is User\n",[33,3512,3513,3515,3517,3519,3521,3523,3525,3527,3529,3531,3533,3536,3538,3540],{"class":35,"line":116},[33,3514,209],{"class":65},[33,3516,3436],{"class":69},[33,3518,215],{"class":73},[33,3520,2857],{"class":86},[33,3522,221],{"class":73},[33,3524,2834],{"class":69},[33,3526,236],{"class":73},[33,3528,90],{"class":65},[33,3530,1609],{"class":69},[33,3532,74],{"class":73},[33,3534,3535],{"class":69},"User",[33,3537,431],{"class":73},[33,3539,434],{"class":65},[33,3541,3542],{"class":65}," ???\n",[33,3544,3545,3547,3549,3551,3553,3555,3557,3559,3561,3563,3565],{"class":35,"line":122},[33,3546,209],{"class":65},[33,3548,3464],{"class":69},[33,3550,215],{"class":73},[33,3552,3469],{"class":86},[33,3554,221],{"class":73},[33,3556,3535],{"class":69},[33,3558,236],{"class":73},[33,3560,90],{"class":65},[33,3562,2814],{"class":69},[33,3564,276],{"class":65},[33,3566,3542],{"class":65},[33,3568,3569],{"class":35,"line":128},[33,3570,47],{"emptyLinePlaceholder":46},[33,3572,3573,3575,3578,3580,3582],{"class":35,"line":149},[33,3574,66],{"class":65},[33,3576,3577],{"class":69}," OrderRepo",[33,3579,2198],{"class":65},[33,3581,3416],{"class":69},[33,3583,203],{"class":65},[33,3585,3586,3588,3590,3592,3595],{"class":35,"line":155},[33,3587,3423],{"class":65},[33,3589,3426],{"class":69},[33,3591,276],{"class":65},[33,3593,3594],{"class":69}," Order",[33,3596,3597],{"class":39},"                    \u002F\u002F concrete: Entity is Order\n",[33,3599,3600,3602,3604,3606,3608,3610,3612,3614,3616,3618,3620,3623,3625,3627],{"class":35,"line":161},[33,3601,209],{"class":65},[33,3603,3436],{"class":69},[33,3605,215],{"class":73},[33,3607,2857],{"class":86},[33,3609,221],{"class":73},[33,3611,2834],{"class":69},[33,3613,236],{"class":73},[33,3615,90],{"class":65},[33,3617,1609],{"class":69},[33,3619,74],{"class":73},[33,3621,3622],{"class":69},"Order",[33,3624,431],{"class":73},[33,3626,434],{"class":65},[33,3628,3542],{"class":65},[33,3630,3631,3633,3635,3637,3639,3641,3643,3645,3647,3649,3651],{"class":35,"line":166},[33,3632,209],{"class":65},[33,3634,3464],{"class":69},[33,3636,215],{"class":73},[33,3638,3469],{"class":86},[33,3640,221],{"class":73},[33,3642,3622],{"class":69},[33,3644,236],{"class":73},[33,3646,90],{"class":65},[33,3648,2814],{"class":69},[33,3650,276],{"class":65},[33,3652,3542],{"class":65},[33,3654,3655],{"class":35,"line":172},[33,3656,47],{"emptyLinePlaceholder":46},[33,3658,3659],{"class":35,"line":178},[33,3660,3661],{"class":39},"\u002F\u002F The type repo.Entity depends on which repo instance you use\n",[33,3663,3664,3666,3669,3671,3674,3676,3679,3681,3684,3686,3688,3691,3693,3696,3698,3700,3702,3705,3707,3709],{"class":35,"line":184},[33,3665,607],{"class":65},[33,3667,3668],{"class":69}," transfer",[33,3670,215],{"class":73},[33,3672,3673],{"class":86},"from",[33,3675,221],{"class":73},[33,3677,3678],{"class":69},"Repository",[33,3680,226],{"class":73},[33,3682,3683],{"class":86},"to",[33,3685,221],{"class":73},[33,3687,3678],{"class":69},[33,3689,3690],{"class":73},")(",[33,3692,3469],{"class":86},[33,3694,3695],{"class":73},": from.",[33,3697,3455],{"class":69},[33,3699,236],{"class":73},[33,3701,90],{"class":65},[33,3703,3704],{"class":73}," to.",[33,3706,3455],{"class":69},[33,3708,276],{"class":65},[33,3710,3542],{"class":65},[33,3712,3713],{"class":35,"line":206},[33,3714,3715],{"class":39},"\u002F\u002F from.Entity and to.Entity are different types — can't mix them.\n",[33,3717,3718],{"class":35,"line":244},[33,3719,3720],{"class":39},"\u002F\u002F This prevents passing a User to an OrderRepo — type-safe at compile time.\n",[15,3722,3724],{"id":3723},"tips-tricks","💡 Tips & Tricks",[3726,3727,3728,221,3735,3738],"p",{},[3729,3730,3731,3734],"strong",{},[30,3732,3733],{},"summon[T]"," to verify type evidence at compile time",[30,3736,3737],{},"summon[T =:= U]"," succeeds only if T and U are the same type — use for compile-time assertions.",[20,3740,3741],{"language":22},[24,3742,3744],{"className":26,"code":3743,"language":22,"meta":28,"style":28},"summon[Int =:= Int]                        \u002F\u002F compiles (evidence exists)\n\u002F\u002F summon[Int =:= String]                  \u002F\u002F compile error (no evidence)\n",[30,3745,3746,3763],{"__ignoreMap":28},[33,3747,3748,3750,3752,3755,3757,3760],{"class":35,"line":36},[33,3749,3231],{"class":73},[33,3751,689],{"class":69},[33,3753,3754],{"class":65}," =:=",[33,3756,2296],{"class":69},[33,3758,3759],{"class":73},"]                        ",[33,3761,3762],{"class":39},"\u002F\u002F compiles (evidence exists)\n",[33,3764,3765,3768],{"class":35,"line":43},[33,3766,3767],{"class":39},"\u002F\u002F summon[Int =:= String]",[33,3769,3770],{"class":39},"                  \u002F\u002F compile error (no evidence)\n",[3726,3772,3773,221,3779,3782],{},[3729,3774,3775,3778],{},[30,3776,3777],{},"\u003C:\u003C"," for safe downcasts",[30,3780,3781],{},"def f(x: Any)(using ev: x.type \u003C:\u003C String)"," — only callable when the compiler can prove the type relationship.",[3726,3784,3785,3788,3789,3791],{},[3729,3786,3787],{},"Given instances in companion objects for automatic availability",": Place ",[30,3790,545],{}," instances in the companion of the type class — they're always in scope without imports.",[15,3793,3795],{"id":3794},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[3726,3797,3798,3801,3802,3805,3806,3809],{},[3729,3799,3800],{},"Variance and arrays",": Scala ",[30,3803,3804],{},"Array[T]"," is INVARIANT (unlike Java's covariant arrays). This prevents ",[30,3807,3808],{},"ArrayStoreException"," at compile time — a deliberate fix.",[3726,3811,3812,221,3815,3818,3819,3822,3823,3825,3826,3829,3830,3833],{},[3729,3813,3814],{},"Type erasure breaks pattern matching on generics",[30,3816,3817],{},"case x: List[Int]"," and ",[30,3820,3821],{},"case x: List[String]"," match the SAME thing at runtime (both are ",[30,3824,860],{},"). Use ",[30,3827,3828],{},"ClassTag"," or ",[30,3831,3832],{},"TypeTest"," for reified type checks.",[3726,3835,3836,3841],{},[3729,3837,3838,3840],{},[30,3839,545],{}," ambiguity is a compile error, not a runtime error",": Two givens of the same type in scope → the compiler refuses to pick. Unlike implicit resolution in Scala 2 (which sometimes picked \"more specific\"), Scala 3 requires explicit disambiguation.",[3726,3843,3844,3847],{},[3729,3845,3846],{},"Phantom types increase type complexity",": Overuse makes signatures hard to read. Use for genuine state-machine constraints (connection states, builder phases), not for trivial distinctions.",[15,3849,3851],{"id":3850},"quick-quiz","🧠 Quick Quiz",[3726,3853,3854,3855,3858,3859,226,3862,3865,3866,3869,3870,3873],{},"Why does ",[30,3856,3857],{},"List[Any]"," accept ",[30,3860,3861],{},"List[Int]",[30,3863,3864],{},"List[String]",", etc., but ",[30,3867,3868],{},"Array[Any]"," does NOT accept ",[30,3871,3872],{},"Array[Int]","?",[3875,3876,3877,3881,3950],"details",{},[3878,3879,3880],"summary",{},"Answer",[3882,3883,3884,3914],"ul",{},[3885,3886,3887,3889,3890,3893,3894,3897,3898,3901,3902,3904,3905,3907,3908,3910,3911,3913],"li",{},[30,3888,860],{}," is covariant (",[30,3891,3892],{},"List[+T]","). ",[30,3895,3896],{},"List[Int] \u003C: List[Any]"," because ",[30,3899,3900],{},"Int \u003C: Any",". This is safe because ",[30,3903,860],{}," is immutable — you can't add a ",[30,3906,746],{}," to a ",[30,3909,3861],{}," (it returns a new ",[30,3912,860],{},", the original is unchanged).",[3885,3915,3916,3919,3920,3893,3922,3924,3925,3901,3927,3929,3930,3932,3933,3935,3936,3939,3940,3942,3943,3946,3947,3949],{},[30,3917,3918],{},"Array"," is invariant (",[30,3921,3804],{},[30,3923,3872],{}," is NOT a subtype of ",[30,3926,3868],{},[30,3928,3918],{}," is mutable — if ",[30,3931,3872],{}," were a subtype of ",[30,3934,3868],{},", you could do ",[30,3937,3938],{},"val anyArr: Array[Any] = intArr; anyArr(0) = \"string\""," — a ",[30,3941,746],{}," in an ",[30,3944,3945],{},"int[]"," would be an ",[30,3948,3808],{}," at runtime.",[3726,3951,3952,3953,3955],{},"Scala learned from Java's mistake (Java arrays are covariant and DO throw ",[30,3954,3808],{}," at runtime). Scala's invariant arrays prevent this at compile time.",[3957,3958,3959],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":28,"searchDepth":43,"depth":43,"links":3961},[3962,3963,3964,3966,3967,3969,3970,3971,3972,3973,3974,3975],{"id":17,"depth":43,"text":18},{"id":342,"depth":43,"text":343},{"id":541,"depth":43,"text":3965},"Type Classes with given \u002F using — Scala 3",{"id":1020,"depth":43,"text":1021},{"id":1354,"depth":43,"text":3968},"Higher-Kinded Types — F[_]",{"id":2145,"depth":43,"text":2146},{"id":2768,"depth":43,"text":2769},{"id":3043,"depth":43,"text":3044},{"id":3396,"depth":43,"text":3397},{"id":3723,"depth":43,"text":3724},{"id":3794,"depth":43,"text":3795},{"id":3850,"depth":43,"text":3851},"md",{},"\u002Fscala\u002F08-type-system",{"title":3980,"description":28},{"Scala — Type System":3981,"description":3982},"Variance, Bounds, Givens & Phantom Types","Deep-dive into Scala 3's type system — variance annotations and their constraints, upper\u002Flower bounds, context abstractions (given\u002Fusing), type classes, higher-kinded types, phantom types for compile-time state machines, and match types.","scala\u002F08-type-system","WWBWqqxOzx4IJ1o3em3sBWIq9Rj4sJFOuwLwK3o8k4o",1789924654079]