{"id":361234,"date":"2024-05-21T01:09:32","date_gmt":"2024-05-21T01:09:32","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=361234"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=361234","title":{"rendered":"<span>Scala 3 Metaprogramming: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0442\u044c \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0430\u0434 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0435\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>List[A].head<\/code> \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u0441\u0442\u043e\u0439. \u042d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439: \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 <code>List[A].size > 0<\/code>.<\/p>\n<p>\u0410 \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438?<br \/> \u0414\u0430, \u0435\u0441\u043b\u0438 <em>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0442\u0438\u043f\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440<\/em>. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b, \u0430 \u043a\u0430\u043a\u0438\u0435 &#8212; \u043d\u0435\u0442.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e \u0441\u0432\u044f\u0437\u043d\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u044f \u043d\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0442 \u0432 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 &#171;\u0447\u0430\u0439\u043d\u0438\u043a\u043e\u0432&#187;. \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0434\u0430, \u043e\u043f\u0438\u0448\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u0432\u0441\u0435\u043c <s>\u0431\u0435\u0437\u0434\u0435\u043b\u044c\u043d\u0438\u043a\u0430\u043c<\/s> \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f\u043c Scala, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u043e\u0433\u0430\u0442\u044c \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 Scala 3, \u043d\u043e \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c. \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0437\u044b\u043a\u0430:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html\" rel=\"noopener noreferrer nofollow\"><code>inline<\/code>-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 <code>inline match<\/code><\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.rockthejvm.com\/new-types-scala-3\/#1-literal-types\" rel=\"noopener noreferrer nofollow\">\u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/metaprogramming\/compiletime-ops.html\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/a> (<a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime.html\" rel=\"noopener noreferrer nofollow\">scala.compiletime<\/a>).<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c \u0432\u0430\u0441 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e \u043a\u043e\u043d\u0446\u0430, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<pre><code class=\"scala\">\/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 val intList: SList[Int, 3] = 1 :: 2 :: 3 :: SNil val stringList: SList[String, 2] = \"foo\" :: \"bar\" :: SNil  \/\/ \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 val emptyList: SList[Int, 0] = SNil intList.refined \/\/ SCons[Int, 2] emptyList.refined \/\/ SNil.type  \/\/ \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 head \u0438 tail stringList.head \/\/ foo stringList.tail \/\/ SList(bar): SList[String, 1]  \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 stringList.tail.tail.head stringList.tail.tail.tail  \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 map\/flatMap  \/\/ SList(1foo,1bar,2foo,2bar,3foo,3bar) val combinedList: SList[String, 6] = for { int &lt;- intList string &lt;- stringList resultValue = int.toString + string } yield resultValue <\/code><\/pre>\n<pre><code class=\"scala\">val intList: SList[Int, 3] = 1 :: 2 :: 3 :: SNil val stringList: SList[String, 2] = \"foo\" :: \"bar\" :: SNil  \/\/ SList(1foo,1bar,2foo,2bar,3foo,3bar) val combinedList: SList[String, 6] = for { int &lt;- intList string &lt;- stringList resultValue = int.toString + string } yield resultValue <\/code><\/pre>\n<h2>ADT-\u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/h2>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>List[A]<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0442\u0438\u043f-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  sealed trait SList[+A, N &lt;: Int]  case object SNil extends SList[Nothing, 0]  case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])  extends SList[A, S[N]] <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b N \u0438 S[N]<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 Scala 3 \u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  val three: 3 = 3 val four: 2 + 2 = 4 val myTrue: true = true val myFalse: 3 &lt; 2 = false \/\/ compile error val error: 4 = 3 <\/code><\/pre>\n<p>\u0426\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u043c <code>Int<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0438\u0441\u044c <code>N &lt;: Int<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b.<br \/> <a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime\/ops\/int%24.html#S-0\" rel=\"noopener noreferrer nofollow\"><code>S[N]<\/code><\/a> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u0430 <code>N<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b <code>SList.head<\/code> \u0438 <code>SList.tail<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u0441\u043f\u0438\u0441\u043a\u0430:<\/p>\n<pre><code class=\"scala\">def head(using N > 0 =:= true): A =  this.asInstanceOf[SCons[A, N - 1]].head def tail(using N > 0 =:= true): SList[A, N - 1] =  this.asInstanceOf[SCons[A, N - 1]].tail <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0432 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>N > 0 =:= true<\/code>, \u043c\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u043c, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u044b <code>SList.head<\/code> \u0438 <code>SList.tail<\/code> \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0431\u0443\u043b\u0435\u0432 \u043b\u0438\u0442\u0435\u0440\u0430\u043b <code>N > 0<\/code> \u0440\u0430\u0432\u0435\u043d (<code>=:=<\/code>) <code>true<\/code>.<br \/> \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0435\u044f\u0432\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>N > 0 =:= true<\/code>, \u0435\u0441\u043b\u0438 <code>N<\/code> \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>::<\/code> \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"scala\">def ::[A1 >: A](x: A1): SList[A1, S[N]] = SCons(x, this) <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>map<\/code> \u0438\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>:+<\/code>:<\/p>\n<pre><code class=\"scala\">def :+[A1 >: A](x: A1): SList[A1, S[N]] = this match {     case SCons(v, vs) => v :: (vs :+ x)     case SNil => x :: SNil }  def map[B](f: A => B): SList[B, N] = this match {     case SCons(v, vs) => f(v) :: vs.map(f)     case SNil => SNil } <\/code><\/pre>\n<p><em>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <\/em><code><em>List[A]<\/em><\/code><em> \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <\/em><code><em>foldLeft<\/em><\/code><em>.<\/em><\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"scala\">\/\/ val list: SList[Int, 2] = SCons(1,SCons(2,SNil)) val list = 1 :: 2 :: SNil  \/\/ val res0: Int = 1 list.head  \/\/ res1: SList[Int, 1] = SCons(2,SNil) list.tail  \/\/ compile error: Cannot prove that (0 : Int) > (0 : Int) =:= (true : Boolean). list.tail.tail.head  \/\/ compile error: Cannot prove that (0 : Int) > (0 : Int) =:= (true : Boolean). list.tail.tail.tail  \/\/ val res2: SList[String, 2] = SCons(2,SCons(4,SNil)) list.map(x => (x * 2).toString) <\/code><\/pre>\n<h2>Challenge #1: \u0410 \u043c\u043e\u0436\u0435\u0442 \u043b\u0438 N \u0431\u044b\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0443\u043b\u044f?<\/h2>\n<p>\u0424\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e &#8212; \u0434\u0430. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430 <code>SList[A, N]<\/code> \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0447\u0438\u0441\u043b\u0430\u043c\u0438.<br \/> \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>head<\/code>\/<code>tail<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0442\u0440\u0435\u0439\u0442\u0443 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440:<\/p>\n<pre><code class=\"scala\">sealed trait SList[+A, N &lt;: Int](using N >= 0 =:= true) { \/* *\/ }  case object SNil extends SList[Nothing, 0]  \/\/ compile error: Cannot prove that S[N] >= (0 : Int) =:= (true : Boolean) case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])  extends SList[A, S[N]] <\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 Scala <em>\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u044c<\/em>, \u0447\u0442\u043e <code>S[N] >= 0<\/code>, \u0435\u0441\u043b\u0438 <code>N >= 0<\/code>. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0441\u043f\u0435\u0445\u0443, \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0443 <code>java.lang.AssertionError: assertion failed while typechecking<\/code>:<\/p>\n<pre><code class=\"scala\">given [N &lt;: Int](using N >= 0 =:= true): (S[N] >= 0 =:= true) = summon  import scala.compiletime.summonInline inline given [N &lt;: Int](using N >= 0 =:= true): (S[N] >= 0 =:= true) =  summonInline <\/code><\/pre>\n<p><a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime.html#summonInline-fffff7c4\" rel=\"noopener noreferrer nofollow\"><em>summonInline<\/em><\/a><em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u044f\u0432\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/em><\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u044f, \u0443\u0441\u0442\u0430\u0432 \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c, \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b \u043f\u043e\u043c\u043e\u0449\u044c \u043d\u0430 \/r\/Scala, \u0438, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0432 <a href=\"https:\/\/www.reddit.com\/r\/scala\/comments\/17yknng\/comment\/k9vex2b\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0432\u0435\u0442<\/a> \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 Reddit, \u043f\u0440\u0438\u0448\u0435\u043b \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 <code>N >= 0<\/code> \u0438 <code>N > 0<\/code> \u0432 \u0432\u0438\u0434\u0435 <code>GeqZ[N]<\/code> \u0438 <code>GtZ[N]<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  sealed trait GeqZ[N &lt;: Int] object GeqZ {     given[N &lt;: Int](using N >= 0 =:= true): GeqZ[N] = new GeqZ[N] {} }  sealed trait GtZ[N &lt;: Int] extends GeqZ[N] object GtZ {     given[N &lt;: Int](using N > 0 =:= true): GtZ[N] = new GtZ[N] {}      \/\/ \u042f\u0432\u043d\u043e\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e, \u0447\u0442\u043e S[N] > 0, \u0435\u0441\u043b\u0438 N >= 0     def snNext[N &lt;: Int](using GeqZ[N]): GtZ[S[N]] = new GtZ[S[N]] {} } <\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>GeqZ[N]<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438, \u0442\u043e <code>N<\/code> &#8212; \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e <code>N<\/code> &#8212; \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442.\u0435. \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>N >= 0 =:= true<\/code>, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 <code>GeqZ[N]<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 <code>N<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>GeqZ[N]<\/code>, \u0442\u043e \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 <code>S[N]<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>GtZ[N]<\/code> \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>GtZ.snNext<\/code>. <code>GtZ[N]<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e <code>N > 0<\/code>.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0447\u0435\u043c\u0443 snNext \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u0430 \u043a\u0430\u043a given-\u0444\u0443\u043d\u043a\u0446\u0438\u044f?<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 <code>N > 0<\/code> \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439, &#171;\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439&#187; \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0432\u043e\u0434\u0430 <code>GtZ[N]<\/code> \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0442\u043e\u0440\u044b\u043c.<br \/> \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 <code>GtZ[N]<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0435\u0449\u0435 <code>N - 1<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 (\u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0430\u043a\u0441\u0438\u043e\u043c\u0430\u0442\u0438\u043a\u0443 \u041f\u0435\u0430\u043d\u043e), \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043e\u043d \u0440\u0430\u0434\u043e\u0441\u0442\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 <code>StackOverflowError<\/code> \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>summon[GtZ[1000]]<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c ADT-\u043c\u043e\u0434\u0435\u043b\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>GeqZ[N]<\/code>, \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e <code>N >= 0<\/code>, \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">sealed trait SList[+A, N &lt;: Int](using GeqZ[N]) { \/\/ head\/tail \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 N > 0, \u0442.\u0435. \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 GtZ[N] def head(using GtZ[N]): A = \/* *\/     def tail(using GtZ[N]): SList[A, N - 1] = \/* *\/ } case object SNil extends SList[Nothing, 0] case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])(using GeqZ[N])  extends SList[A, S[N]](using GtZ.snNext) <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>head<\/code>\/<code>tail<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u043a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"scala\">val list = 1 :: 2 :: SNil list.head \/\/ 1 list.tail \/\/ SList(2)  \/\/ compile error: No given instance of type GtZ[(0 : Int)] was found \/\/ for parameter x$1 of method head in trait SList. list.tail.tail.head <\/code><\/pre>\n<h2>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u043d\u0430\u0435\u043c N, \u0442\u043e \u043c\u044b \u0432\u0435\u0434\u044c \u0437\u043d\u0430\u0435\u043c \u0438 \u0442\u0438\u043f \u0441\u043f\u0438\u0441\u043a\u0430, \u043f\u0440\u0430\u0432\u0434\u0430?<\/h2>\n<p>\u0417\u0432\u0443\u0447\u0438\u0442 \u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043e\u0434\u043d\u0430\u043a\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f\u043e\u043c <code>N<\/code> \u043a\u0430\u043a \u0447\u0438\u0441\u043b\u043e\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<p>\u0418 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e &#8212; <code>inline<\/code> \u0438 <code>constValue[N]<\/code>:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#inline-methods\" rel=\"noopener noreferrer nofollow\"><code>inline<\/code><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u0442\u0435\u043b\u043e;<\/p>\n<\/li>\n<li>\n<p><code>constValue[N]: N<\/code> (<a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/metaprogramming\/compiletime-ops.html#constvalue-and-constvalueopt-1\" rel=\"noopener noreferrer nofollow\">reference<\/a>) \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"scala\">inline def size: N = constValue[N] <\/code><\/pre>\n<p>\u041b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e. \u0411\u0435\u0437 <code>inline<\/code> \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>constValue[N]<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f: \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <em>\u043d\u0435 \u0436\u0438\u0432\u0435\u0442 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/em>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u0434.<\/p>\n<p>\u0417\u043d\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0440 <code>N<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0441 \u043a\u0430\u043a\u0438\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u043c <code>SList<\/code> \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c: \u0441 <code>SCons<\/code> \u0438\u043b\u0438 \u0441 <code>SNil<\/code>. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>refined<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>N<\/code>, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 <code>SList<\/code> \u043b\u0438\u0431\u043e \u0432 <code>SCons<\/code>, \u043b\u0438\u0431\u043e \u0432 <code>SNil<\/code>:<\/p>\n<pre><code class=\"scala\">transparent inline def refined: SCons[A, N - 1] | SNil.type =  inline if(constValue[N] == 0) SNil else this.asInstanceOf[SCons[A, N - 1]] <\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0435\u0449\u0435 \u0441 \u043f\u0430\u0440\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 Scala 3:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#inline-conditionals\" rel=\"noopener noreferrer nofollow\"><code>inline if<\/code><\/a> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0443\u0436\u043d\u0443\u044e \u0432\u0435\u0442\u043a\u0443 if.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 inline-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#transparent-inline-methods\" rel=\"noopener noreferrer nofollow\"><code>transparent<\/code><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f &#171;\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u044d\u0442\u043e upper bound.<\/p>\n<\/li>\n<li>\n<p><code>A | B<\/code> &#8212; union-\u0442\u0438\u043f, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u0430\u043a \u0442\u0438\u043f <code>A<\/code>, \u0442\u0430\u043a \u0438 \u0442\u0438\u043f <code>B<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p><em>\u042f\u0432\u043d\u044b\u0439 \u043a\u0430\u0441\u0442 <\/em><code><em>this<\/em><\/code><em> \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 <\/em><code><em>else<\/em><\/code><em>-\u0432\u0435\u0442\u043a\u0435 \u043a\u0430\u043a <\/em><code><em>SCons[A, N - 1]<\/em><\/code><em>. \u041d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u043e\u0434\u0442\u0438\u043f <\/em><code><em>this<\/em><\/code><em>, \u0438 \u0435\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e <\/em><code><em>this<\/em><\/code><em>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 <\/em><code><em>SList[A, N]<\/em><\/code><em>.<\/em><\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>size<\/code> \u0438 <code>refined<\/code> \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0438\u0436\u0435. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f <code>refined<\/code> &#8212; \u043d\u0435 <code>SCons | SNil<\/code>, \u0430 <em>\u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439<\/em>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">\/\/ list: SList[Int, 2] = SCons(1,SCons(2,SNil)) val list = 1 :: 2 :: SNil  \/\/ val res0: Int = 2 list.size  \/\/ val res1: SCons[Int, 1] = SCons(1,SCons(2,SNil)) list.refined  \/\/ val nil: SList[Int, 0] = SNil val nil: SList[Int, 0] = SNil  \/\/ val res2: SNil.type = SNil nil.refined <\/code><\/pre>\n<h3>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f refined<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e <code>refined<\/code> \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c upper bound <code>refined<\/code> \u043a\u0430\u043a <code>SList[A, N]<\/code>: \u0442\u0438\u043f <code>SCons[A, N - 1] | SNil.type<\/code> \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u043c <code>SList[A, N]<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>N<\/code> (<code>N - 1<\/code> \u0438 <code>0<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e).<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 <code>SList[A, ?]<\/code>, \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>constValue[N]<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u0448\u0438\u043c \u044d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>summonFrom<\/code> \u0438 <code>constValueOpt[N]<\/code>:<\/p>\n<pre><code class=\"scala\">transparent inline def refined: SList[A, N] = inline constValueOpt[N] match {     case Some(n) if n == 0 =>         summonFrom {             case given (SNil.type &lt;:&lt; SList[A, N]) => SNil         }     case Some(_) =>         summonFrom {             case given (SCons[A, N - 1] &lt;:&lt; SList[A, N]) =>              this.asInstanceOf[SCons[A, N - 1]]         }     case None => this } <\/code><\/pre>\n<ul>\n<li>\n<p><code>constValueOpt[N]<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Some(n)<\/code>, \u0435\u0441\u043b\u0438 \u0442\u0438\u043f <code>N<\/code> \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0438 <code>None<\/code> \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c <code>N<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0438\u0442\u044c <code>this<\/code>, \u043d\u0435 \u0443\u0442\u043e\u0447\u043d\u044f\u044f \u0442\u0438\u043f.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/metaprogramming\/compiletime-ops.html#summoning-givens-selectively-1\" rel=\"noopener noreferrer nofollow\"><code>summonFrom<\/code><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 <code>MyList &lt;:&lt; SList[A, N]<\/code>, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e <code>MyList<\/code> &#8212; \u043f\u043e\u0434\u0442\u0438\u043f <code>SList[A, N]<\/code>. <\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u043b\u0430\u0434\u0430\u044f \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0436\u0430\u043b\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>SNil<\/code> \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>SList[A, N]<\/code> \u043f\u0440\u0438 <code>N == 0<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043b\u0438\u0441\u0438\u0442 <code>&lt;:&lt;<\/code> \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>case Some(n) if n == 0 => SNil<\/code>, \u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0438\u0437-\u0437\u0430 <code>type mismatch<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u041f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433 \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u043b\u0430\u0439\u043d\u0438\u0442\u044c \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>inline if<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <code>inline value match<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>refined<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0448\u0442\u0430\u0442\u043d\u043e:<\/p>\n<pre><code class=\"scala\">\/\/ val list: SList[Int, 1] = SCons(1,SNil) val list: SList[Int, 1] = 1 :: SNil  \/\/ val res0: SCons[Int, 0] = SCons(1,SNil) list.refined  \/\/ val nil: SList[Int, 0] = SNil val nil: SList[Int, 0] = SNil  \/\/ val res1: SNil.type = SNil nil.refined  \/\/ val unsized: SList[Int, ?] = SCons(1,SNil) val unsized: SList[Int, ?] = list  \/\/ val res2: SList[Int, ?] = SCons(1,SNil) unsized.refined <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 (\u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434), \u043d\u043e \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c `match`<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>refined<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433\u0430?<\/p>\n<pre><code class=\"scala\">transparent inline def refined: SCons[A, N - 1] | SNil.type =  this match {     case cons: SCons[A, N - 1] => cons     case SNil => SNil } <\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u043d\u0435\u043f\u0443\u0441\u0442\u044b\u0445 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435:<\/p>\n<pre><code class=\"scala\">val list: SList[Int, 2] = 1 :: 2 :: SNil  list.refined  -- [E007] Type Mismatch Error: ------------------------------------------------- 1 |list.refined   |^^^^^^^^^^^^   |Found:    SCons[Int, (1 : Int)] | SNil.type   |Required: SList[Int, ? >: (2 : Int) &amp; (0 : Int) &lt;: (2 : Int) | (0 : Int)]  <\/code><\/pre>\n<p>\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438&#8230; \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e:<\/p>\n<pre><code class=\"scala\">val nil: SList[Int, 0] = SNil  \/\/val res0: \/\/  SList[Int, ? \/\/     >: scala.compiletime.ops.int.S[-1] &amp; 0 &lt;: scala.compiletime.ops.int.S[-1] | \/\/       0 \/\/  ] = SNil  nil.refined  <\/code><\/pre>\n<p>\u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e <code>match<\/code> \u043d\u0435 \u0437\u0430\u0438\u043d\u043b\u0430\u0439\u043d\u0435\u043d \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>transparent<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0437\u0430\u0438\u043d\u043b\u0430\u0439\u043d\u0438\u0442\u044c?<\/p>\n<pre><code class=\"scala\">transparent inline def refined: SCons[A, N - 1] | SNil.type =  inline this match {     case cons: SCons[A, N - 1] => cons     case SNil => SNil } <\/code><\/pre>\n<p>\u0421\u043d\u043e\u0432\u0430 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u043d\u043e \u0443\u0436\u0435 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0430:<\/p>\n<pre><code class=\"scala\">val list: SList[Int, 2] = 1 :: 2 :: SNil list.refined  -- Error: ----------------------------------------------------------------------  1 |list.refined    |^^^^^^^^^^^^    |cannot reduce inline match with    | scrutinee:  SList_this : (SList_this : (list : SList[Int, (2 : Int)]))    | patterns :  case cons @ _:SCons[Int, scala.compiletime.ops.int.-[N, 1.type]]    |             case SNil  val nil: SList[Int, 0] = SNil nil.refined -- Error: ----------------------------------------------------------------------  1 |nil.refined    |^^^^^^^^^^^    |cannot reduce inline match with    | scrutinee:  SList_this : (SList_this : (nil : SList[Int, (0 : Int)]))    | patterns :  case cons @ _:SCons[Int, scala.compiletime.ops.int.-[N, 1.type]]    |             case SNil <\/code><\/pre>\n<p>\u0421\u0443\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438: <code>inline match<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0438 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0435\u0433\u043e \u0432\u0435\u0442\u043e\u043a \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p><em>\u041f\u043e\u0447\u0435\u043c\u0443, \u0432\u0435\u0434\u044c \u0443 list \u0442\u0438\u043f SCons[Int, 2 &#8212; 1]?<\/em><br \/> \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b <em>\u043d\u0435 \u0437\u043d\u0430\u0435\u043c<\/em> \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438; \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e &#8212; \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e <code>list<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>SList[Int, 2]<\/code>:<\/p>\n<pre><code class=\"scala\">val list: SList[Int, 2] = ??? <\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Challenge #2: \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>flatMap<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 for-comprehension \u0434\u043b\u044f <code>SList<\/code>, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043a\u0438. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u0435-\u043a\u043e\u043c\u043f\u0430\u043d\u044c\u043e\u043d\u0435.<br \/> \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438:<\/p>\n<pre><code class=\"scala\">def add[A, N1 &lt;: Int, N2 &lt;: Int]( list1: SList[A, N1], list2: SList[A, N2] ): SList[A, N1 + N2] = list1 match {     case SCons(x, xs) => x :: add(xs, list2)     case SNil => list2 } <\/code><\/pre>\n<p>\u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043e\u0442\u0432\u0435\u0442:<\/p>\n<pre><code class=\"scala\">[error] -- [E007] Type Mismatch Error: SList.scala  [error] 46 |        case SCons(x, xs) => x :: add(xs, list2) [error]    |                             ^^^^^^^^^^^^^^^^^^^ [error]    |Found:    SList[A, compiletime.ops.int.S[Int + N2]] [error]    |Required: SList[A, N1 + N2] [error]    | [error]    |where:    N1 is a type in method add which is an alias of compiletime.ops.int.S[Int] [error]    |          N2 is a type in method add with bounds &lt;: Int [error]    | [error] -- [E007] Type Mismatch Error: SList.scala [error] 47 |        case SNil => list2 [error]    |                     ^^^^^ [error]    |     Found:    (list2 : SList[A, N2]) [error]    |     Required: SList[A, N1 + N2] [error]    | [error]    |     where:    N1 is a type in method add which is an alias of (0 : Int) [error]    |               N2 is a type in method add with bounds &lt;: Int  <\/code><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043d\u043e\u0432\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0412 <code>case SNil<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 <code>SList[A, N2]<\/code>, \u0430 \u043d\u0435 <code>SList[A, N1 + N2]<\/code>; \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0447\u0442\u043e <code>N1 = 0<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412 <code>case SCons<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u0433\u0430\u0434\u043e\u0447\u043d\u044b\u0439 <code>Int<\/code> &#8212; \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e <code>N0<\/code> \u0442\u0430\u043a\u043e\u0435, \u0447\u0442\u043e <code>S[N0] = N<\/code>, \u043d\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u043c \u0442\u0438\u043f\u0435 \u043e\u0431\u0449\u0438\u0439 <code>Int<\/code>, \u0430 \u043d\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u0418 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044b \u043e\u043d \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u043b, \u043e\u043d \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0441\u043c\u043e\u0433 \u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438, \u0447\u0442\u043e <code>S[N0 + N2] = S[N0] + N2<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u044b \u0443\u0436\u0435 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0441 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0440\u0430\u043d\u0435\u0435, \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>refined<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433 \u043f\u043e <code>constValueOpt[N]<\/code>:<\/p>\n<pre><code class=\"scala\">inline def add[A, N1 &lt;: Int, N2 &lt;: Int]( list1: SList[A, N1], list2: SList[A, N2] ): SList[A, N1 + N2] =     inline constValueOpt[N1] match {         case Some(n) if n == 0 =>             summonFrom {                 case given (SList[A, N2] =:= SList[A, N1 + N2]) =>                  list2             }         case Some(_) =>             val SCons(x, xs) = list1.asInstanceOf[SCons[A, N1 - 1]]             summonFrom {                 case given (SList[A, S[N1 - 1 + N2]] =:= SList[A, N1 + N2]) =>                  x :: add(xs, list2)             }         case _ => ???     } <\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0449\u0435\u043c \u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b <code>MyList =:= SList[A, N1 + N2]<\/code>, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043c\u043e\u0433 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>N1<\/code> \u0438 <code>N2<\/code>.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>refined<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>add<\/code>:<\/p>\n<pre><code class=\"scala\">inline def addUsingRefined[A, N1 &lt;: Int, N2 &lt;: Int]( list1: SList[A, N1], list2: SList[A, N2] ): SList[A, N1 + N2] =     inline list1.refined match {         case cons: SCons[A, N1 - 1] =>             summonFrom {                 case given (SList[A, S[N1 - 1 + N2]] =:= SList[A, N1 + N2]) =>                  cons.head :: add(cons.tail, list2)             }         case _: SNil.type =>             summonFrom {                 case given (SList[A, N2] =:= SList[A, N1 + N2]) =>                  list2             }     } <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0438\u043f <code>list1.refined<\/code> <em>\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d<\/em> \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e <code>N<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c inline matching \u043f\u043e \u043d\u0435\u043c\u0443.<\/p>\n<p>\u041e\u0431\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u043e:<\/p>\n<pre><code class=\"scala\">val list1: SList[Int, 3] = 1 :: 2 :: 3 :: SNil val list2: SList[Int, 3] = 4 :: 5 :: 6 :: SNil val nil: SList[Int, 0] = SNil  \/\/val res0: SList[Int, 6] = SList(1,2,3,4,5,6) SList.add(list1, list2) \/\/val res1: SList[Int, 3] = SList(4,5,6) SList.add(nil, list2) \/\/val res3: SList[Int, 3] = SList(1,2,3) SList.add(list1, nil)  \/\/ true SList.add(list1, list2) == SList.addUsingRefined(list1, list2) SList.add(nil, list2) == SList.addUsingRefined(nil, list2) SList.add(list1, nil) == SList.addUsingRefined(list1, nil) <\/code><\/pre>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <code>add<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0432 \u0442\u0440\u0435\u0439\u0442\u0435 <code>SList<\/code>. \u0412\u0430\u0436\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u0438 \u0434\u0430\u043b\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>inline<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>constValue[N]<\/code>:<\/p>\n<pre><code class=\"scala\">inline def :::[A1 >: A, N1 &lt;: Int](begin: SList[A1, N1]): SList[A1, N1 + N] =  SList.add(begin, this) inline def ++[A1 >: A, N1 &lt;: Int](end: SList[A1, N1]): SList[A1, N + N1] =  SList.add(this, end) <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u0442\u0435\u0440\u0435\u0432 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0440\u0430\u043d\u0442\u0430\u0439\u043c-\u043a\u0430\u0441\u0442:<\/p>\n<pre><code class=\"scala\">def addRuntime[A, N1 &lt;: Int, N2 &lt;: Int]( list1: SList[A, N1], list2: SList[A, N2] ): SList[A, N1 + N2] = {     def addUnsized(     list1: SList[A, ?],      list2: SList[A, ?]     ): SList[A, ?] = list1 match {         case SCons(x, xs) => x :: addUnsized(xs, list2)         case SNil => list2     }          addUnsized(list1, list2).asInstanceOf[SList[A, N1 + N2]] } <\/code><\/pre>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 inline-\u0432\u0435\u0440\u0441\u0438\u0438, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u043d\u0435 \u0443\u043f\u0430\u0434\u0435\u0442 \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0435\u043a\u0430 \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 <code>N1<\/code>, <code>N2<\/code>.<\/p>\n<\/div>\n<\/details>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f flatten \u0438 flatMap<\/h2>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u043f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433 \u043f\u043e <code>refined<\/code> \u0438 <code>summonFrom<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>flatten<\/code>, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u0430\u043c:<\/p>\n<pre><code class=\"scala\">inline def flatten[A, N0 &lt;: Int, N &lt;: Int]( list: SList[SList[A, N], N0] ): SList[A, N0 * N] =     inline list.refined match {         case cons: SCons[SList[A, N], N0 - 1] =>             summonFrom {                 case given (SList[A, N + (N0 - 1) * N] =:= SList[A, N0 * N]) =>                  cons.head ::: flatten(cons.tail)             }         case _: SNil.type =>             summonFrom {                 case given (SNil.type &lt;:&lt; SList[A, N0 * N]) =>                  SNil             }     } <\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u043f\u0440\u0438 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u0435\u0439\u0441\u0435 \u043c\u044b \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u043d\u0430\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>SList[A, N0 * N]<\/code>.<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>flatten<\/code> \u0438 <code>map<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>flatMap<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"scala\">inline def flatten[B, N1 &lt;: Int](using ev: A &lt;:&lt; SList[B, N1]): SList[B, N * N1] =  SList.flatten(this.map(ev)) inline def flatMap[B, N1 &lt;: Int](f: A => SList[B, N1]): SList[B, N * N1] =  this.map(f).flatten <\/code><\/pre>\n<p>\u0412 \u0432\u044b\u0437\u043e\u0432\u0435 <code>flatten<\/code> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>ev: A &lt;:&lt; SList[B, N1]<\/code>, \u0447\u0442\u043e\u0431\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f <code>SList<\/code> \u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>ev.apply<\/code> \u0432 <code>map<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>A<\/code> \u043a <code>SList[B, N1]<\/code>. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a <code>SList[SList[B, N1], N]<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0432\u043e <code>flatten<\/code> \u0432 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c for-comprehension:<\/p>\n<pre><code class=\"scala\">\/\/ val intList: SList[Int, 3] = SList(1,2,3) val intList = 1 :: 2 :: 3 :: SNil  \/\/ val stringList: SList[String, 2] = SList(foo,bar) val stringList = \"foo\" :: \"bar\" :: SNil  \/\/ val combinedList: SList[String, 6] = SList(1foo,1bar,2foo,2bar,3foo,3bar) val combinedList = for { int &lt;- intList string &lt;- stringList resultValue = int.toString + string } yield resultValue <\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>Mission completed! \u041c\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a <code>SList[A, N]<\/code> \u0441:<\/p>\n<ul>\n<li>\n<p>\u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c <code>N<\/code>, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 <code>head<\/code>\/<code>tail<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 <code>::<\/code>, <code>:+<\/code>, <code>:::<\/code>, <code>++<\/code>, <code>map<\/code>, <code>flatten<\/code>, <code>flatMap<\/code>, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0449\u0438\u043c\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u0441\u043f\u0438\u0441\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>refined<\/code>, \u0443\u0442\u043e\u0447\u043d\u044f\u044e\u0449\u0435\u0439 \u0442\u0438\u043f \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u043f\u043e \u0445\u043e\u0434\u0443 \u0434\u0435\u043b\u0430 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, compile-time \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 inline-\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 Scala 3 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/skelantros\/sized-list\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a &#8212; \u044d\u0442\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Scala 3, \u043c\u0430\u043b\u043e\u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e:<\/p>\n<ul>\n<li>\n<p>\u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043d\u0435 \u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430, \u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u043a \u0432 \u043a\u043e\u0442\u043e\u0432\u0441\u043a\u043e\u043c <code>NonEmptyList<\/code>.<\/p>\n<\/li>\n<li>\n<p>inline-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f, <code>flatten<\/code> \u0438 <code>flatMap<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0431\u044b\u0441\u0442\u0440\u043e \u0443\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0435\u043b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u0432 inline-\u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e &#8212; 32).<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u043e\u0448\u0443 \u0432\u0430\u0441, \u0434\u043e\u0440\u043e\u0433\u043e\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c, \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445:<\/p>\n<ul>\n<li>\n<p>\u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u044f \u0432\u0430\u0441 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u043b\u0438 \u0432\u0430\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0430-\u043b\u044f &#171;\u0440\u0430\u0437\u0436\u0435\u0432\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0441 \u043a\u0443\u0447\u0435\u0439 \u043a\u043e\u0434\u0430&#187;.<\/p>\n<\/li>\n<\/ul>\n<p>\u041b\u044e\u0431\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u0440\u0438\u0442\u0438\u043a\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442\u0441\u044f \ud83d\ude42<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0430 \u0442\u0435\u043c\u0443 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f &#171;\u0447\u0430\u0439\u043d\u0438\u043a\u043e\u0432&#187;&#8230; \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u0438 \u0441\u0430\u043c \u0440\u0430\u0437\u0431\u0435\u0440\u0443\u0441\u044c.<\/p>\n<p><strong>\u0414\u0430 \u043f\u0440\u0435\u0431\u0443\u0434\u0435\u0442 \u0441 \u0432\u0430\u043c\u0438 \u043c\u0435\u0442\u0430-\u0441\u0438\u043b\u0430!<\/strong><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/776460\/\"> https:\/\/habr.com\/ru\/articles\/776460\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0442\u044c \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0430\u0434 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0435\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>List[A].head<\/code> \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u0441\u0442\u043e\u0439. \u042d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439: \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 <code>List[A].size > 0<\/code>.<\/p>\n<p>\u0410 \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438?<br \/> \u0414\u0430, \u0435\u0441\u043b\u0438 <em>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0442\u0438\u043f\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440<\/em>. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b, \u0430 \u043a\u0430\u043a\u0438\u0435 &#8212; \u043d\u0435\u0442.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e \u0441\u0432\u044f\u0437\u043d\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u044f \u043d\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0442 \u0432 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 &#171;\u0447\u0430\u0439\u043d\u0438\u043a\u043e\u0432&#187;. \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0434\u0430, \u043e\u043f\u0438\u0448\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u0432\u0441\u0435\u043c <s>\u0431\u0435\u0437\u0434\u0435\u043b\u044c\u043d\u0438\u043a\u0430\u043c<\/s> \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f\u043c Scala, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u043e\u0433\u0430\u0442\u044c \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 Scala 3, \u043d\u043e \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c. \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0437\u044b\u043a\u0430:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html\" rel=\"noopener noreferrer nofollow\"><code>inline<\/code>-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 <code>inline match<\/code><\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.rockthejvm.com\/new-types-scala-3\/#1-literal-types\" rel=\"noopener noreferrer nofollow\">\u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/metaprogramming\/compiletime-ops.html\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/a> (<a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime.html\" rel=\"noopener noreferrer nofollow\">scala.compiletime<\/a>).<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c \u0432\u0430\u0441 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e \u043a\u043e\u043d\u0446\u0430, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<pre><code class=\"scala\">\/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 val intList: SList[Int, 3] = 1 :: 2 :: 3 :: SNil val stringList: SList[String, 2] = \"foo\" :: \"bar\" :: SNil  \/\/ \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 val emptyList: SList[Int, 0] = SNil intList.refined \/\/ SCons[Int, 2] emptyList.refined \/\/ SNil.type  \/\/ \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 head \u0438 tail stringList.head \/\/ foo stringList.tail \/\/ SList(bar): SList[String, 1]  \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 stringList.tail.tail.head stringList.tail.tail.tail  \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 map\/flatMap  \/\/ SList(1foo,1bar,2foo,2bar,3foo,3bar) val combinedList: SList[String, 6] = for { int &lt;- intList string &lt;- stringList resultValue = int.toString + string } yield resultValue <\/code><\/pre>\n<pre><code class=\"scala\">val intList: SList[Int, 3] = 1 :: 2 :: 3 :: SNil val stringList: SList[String, 2] = \"foo\" :: \"bar\" :: SNil  \/\/ SList(1foo,1bar,2foo,2bar,3foo,3bar) val combinedList: SList[String, 6] = for { int &lt;- intList string &lt;- stringList resultValue = int.toString + string } yield resultValue <\/code><\/pre>\n<h2>ADT-\u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/h2>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>List[A]<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0442\u0438\u043f-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  sealed trait SList[+A, N &lt;: Int]  case object SNil extends SList[Nothing, 0]  case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])  extends SList[A, S[N]] <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b N \u0438 S[N]<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 Scala 3 \u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  val three: 3 = 3 val four: 2 + 2 = 4 val myTrue: true = true val myFalse: 3 &lt; 2 = false \/\/ compile error val error: 4 = 3 <\/code><\/pre>\n<p>\u0426\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u043c <code>Int<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0438\u0441\u044c <code>N &lt;: Int<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b.<br \/> <a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime\/ops\/int%24.html#S-0\" rel=\"noopener noreferrer nofollow\"><code>S[N]<\/code><\/a> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0437\u0430 <code>N<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b <code>SList.head<\/code> \u0438 <code>SList.tail<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u0441\u043f\u0438\u0441\u043a\u0430:<\/p>\n<pre><code class=\"scala\">def head(using N > 0 =:= true): A =  this.asInstanceOf[SCons[A, N - 1]].head def tail(using N > 0 =:= true): SList[A, N - 1] =  this.asInstanceOf[SCons[A, N - 1]].tail <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0432 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>N > 0 =:= true<\/code>, \u043c\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u043c, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u044b <code>SList.head<\/code> \u0438 <code>SList.tail<\/code> \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0431\u0443\u043b\u0435\u0432 \u043b\u0438\u0442\u0435\u0440\u0430\u043b <code>N > 0<\/code> \u0440\u0430\u0432\u0435\u043d (<code>=:=<\/code>) <code>true<\/code>.<br \/> \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0435\u044f\u0432\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>N > 0 =:= true<\/code>, \u0435\u0441\u043b\u0438 <code>N<\/code> \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>::<\/code> \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"scala\">def ::[A1 >: A](x: A1): SList[A1, S[N]] = SCons(x, this) <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>map<\/code> \u0438\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>:+<\/code>:<\/p>\n<pre><code class=\"scala\">def :+[A1 >: A](x: A1): SList[A1, S[N]] = this match {     case SCons(v, vs) => v :: (vs :+ x)     case SNil => x :: SNil }  def map[B](f: A => B): SList[B, N] = this match {     case SCons(v, vs) => f(v) :: vs.map(f)     case SNil => SNil } <\/code><\/pre>\n<p><em>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <\/em><code><em>List[A]<\/em><\/code><em> \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <\/em><code><em>foldLeft<\/em><\/code><em>.<\/em><\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"scala\">\/\/ val list: SList[Int, 2] = SCons(1,SCons(2,SNil)) val list = 1 :: 2 :: SNil  \/\/ val res0: Int = 1 list.head  \/\/ res1: SList[Int, 1] = SCons(2,SNil) list.tail  \/\/ compile error: Cannot prove that (0 : Int) > (0 : Int) =:= (true : Boolean). list.tail.tail.head  \/\/ compile error: Cannot prove that (0 : Int) > (0 : Int) =:= (true : Boolean). list.tail.tail.tail  \/\/ val res2: SList[String, 2] = SCons(2,SCons(4,SNil)) list.map(x => (x * 2).toString) <\/code><\/pre>\n<h2>Challenge #1: \u0410 \u043c\u043e\u0436\u0435\u0442 \u043b\u0438 N \u0431\u044b\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0443\u043b\u044f?<\/h2>\n<p>\u0424\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e &#8212; \u0434\u0430. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430 <code>SList[A, N]<\/code> \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0447\u0438\u0441\u043b\u0430\u043c\u0438.<br \/> \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>head<\/code>\/<code>tail<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0442\u0440\u0435\u0439\u0442\u0443 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440:<\/p>\n<pre><code class=\"scala\">sealed trait SList[+A, N &lt;: Int](using N >= 0 =:= true) { \/* *\/ }  case object SNil extends SList[Nothing, 0]  \/\/ compile error: Cannot prove that S[N] >= (0 : Int) =:= (true : Boolean) case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])  extends SList[A, S[N]] <\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 Scala <em>\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u044c<\/em>, \u0447\u0442\u043e <code>S[N] >= 0<\/code>, \u0435\u0441\u043b\u0438 <code>N >= 0<\/code>. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0441\u043f\u0435\u0445\u0443, \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0443 <code>java.lang.AssertionError: assertion failed while typechecking<\/code>:<\/p>\n<pre><code class=\"scala\">given [N &lt;: Int](using N >= 0 =:= true): (S[N] >= 0 =:= true) = summon  import scala.compiletime.summonInline inline given [N &lt;: Int](using N >= 0 =:= true): (S[N] >= 0 =:= true) =  summonInline <\/code><\/pre>\n<p><a href=\"https:\/\/scala-lang.org\/api\/3.x\/scala\/compiletime.html#summonInline-fffff7c4\" rel=\"noopener noreferrer nofollow\"><em>summonInline<\/em><\/a><em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u044f\u0432\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/em><\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u044f, \u0443\u0441\u0442\u0430\u0432 \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c, \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b \u043f\u043e\u043c\u043e\u0449\u044c \u043d\u0430 \/r\/Scala, \u0438, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0432 <a href=\"https:\/\/www.reddit.com\/r\/scala\/comments\/17yknng\/comment\/k9vex2b\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0432\u0435\u0442<\/a> \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 Reddit, \u043f\u0440\u0438\u0448\u0435\u043b \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 <code>N >= 0<\/code> \u0438 <code>N > 0<\/code> \u0432 \u0432\u0438\u0434\u0435 <code>GeqZ[N]<\/code> \u0438 <code>GtZ[N]<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e:<\/p>\n<pre><code class=\"scala\">import scala.compiletime.ops.int.*  sealed trait GeqZ[N &lt;: Int] object GeqZ {     given[N &lt;: Int](using N >= 0 =:= true): GeqZ[N] = new GeqZ[N] {} }  sealed trait GtZ[N &lt;: Int] extends GeqZ[N] object GtZ {     given[N &lt;: Int](using N > 0 =:= true): GtZ[N] = new GtZ[N] {}      \/\/ \u042f\u0432\u043d\u043e\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e, \u0447\u0442\u043e S[N] > 0, \u0435\u0441\u043b\u0438 N >= 0     def snNext[N &lt;: Int](using GeqZ[N]): GtZ[S[N]] = new GtZ[S[N]] {} } <\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>GeqZ[N]<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438, \u0442\u043e <code>N<\/code> &#8212; \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e <code>N<\/code> &#8212; \u043d\u0435\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442.\u0435. \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>N >= 0 =:= true<\/code>, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 <code>GeqZ[N]<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 <code>N<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>GeqZ[N]<\/code>, \u0442\u043e \u0434\u043b\u044f \u0447\u0438\u0441\u043b\u0430 <code>S[N]<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>GtZ[N]<\/code> \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>GtZ.snNext<\/code>. <code>GtZ[N]<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e <code>N > 0<\/code>.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0447\u0435\u043c\u0443 snNext \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u0430 \u043a\u0430\u043a given-\u0444\u0443\u043d\u043a\u0446\u0438\u044f?<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 <code>N > 0<\/code> \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439, &#171;\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439&#187; \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0432\u043e\u0434\u0430 <code>GtZ[N]<\/code> \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0442\u043e\u0440\u044b\u043c.<br \/> \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 <code>GtZ[N]<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0435\u0449\u0435 <code>N - 1<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 (\u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0430\u043a\u0441\u0438\u043e\u043c\u0430\u0442\u0438\u043a\u0443 \u041f\u0435\u0430\u043d\u043e), \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043e\u043d \u0440\u0430\u0434\u043e\u0441\u0442\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 <code>StackOverflowError<\/code> \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0432\u0435\u0441\u0442\u0438 <code>summon[GtZ[1000]]<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c ADT-\u043c\u043e\u0434\u0435\u043b\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>GeqZ[N]<\/code>, \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e <code>N >= 0<\/code>, \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">sealed trait SList[+A, N &lt;: Int](using GeqZ[N]) { \/\/ head\/tail \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 N > 0, \u0442.\u0435. \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 GtZ[N] def head(using GtZ[N]): A = \/* *\/     def tail(using GtZ[N]): SList[A, N - 1] = \/* *\/ } case object SNil extends SList[Nothing, 0] case class SCons[+A, N &lt;: Int](head: A, tail: SList[A, N])(using GeqZ[N])  extends SList[A, S[N]](using GtZ.snNext) <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>head<\/code>\/<code>tail<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u043a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"scala\">val list = 1 :: 2 :: SNil list.head \/\/ 1 list.tail \/\/ SList(2)  \/\/ compile error: No given instance of type GtZ[(0 : Int)] was found \/\/ for parameter x$1 of method head in trait SList. list.tail.tail.head <\/code><\/pre>\n<h2>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u043d\u0430\u0435\u043c N, \u0442\u043e \u043c\u044b \u0432\u0435\u0434\u044c \u0437\u043d\u0430\u0435\u043c \u0438 \u0442\u0438\u043f \u0441\u043f\u0438\u0441\u043a\u0430, \u043f\u0440\u0430\u0432\u0434\u0430?<\/h2>\n<p>\u0417\u0432\u0443\u0447\u0438\u0442 \u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043e\u0434\u043d\u0430\u043a\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f\u043e\u043c <code>N<\/code> \u043a\u0430\u043a \u0447\u0438\u0441\u043b\u043e\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<p>\u0418 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e &#8212; <code>inline<\/code> \u0438 <code>constValue[N]<\/code>:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#inline-methods\" rel=\"noopener noreferrer nofollow\"><code>inline<\/code><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u0442\u0435\u043b\u043e;<\/p>\n<\/li>\n<li>\n<p><code>constValue[N]: N<\/code> (<a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/metaprogramming\/compiletime-ops.html#constvalue-and-constvalueopt-1\" rel=\"noopener noreferrer nofollow\">reference<\/a>) \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"scala\">inline def size: N = constValue[N] <\/code><\/pre>\n<p>\u041b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e. \u0411\u0435\u0437 <code>inline<\/code> \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>constValue[N]<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f: \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <em>\u043d\u0435 \u0436\u0438\u0432\u0435\u0442 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/em>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u0434.<\/p>\n<p>\u0417\u043d\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0440 <code>N<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0441 \u043a\u0430\u043a\u0438\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u043c <code>SList<\/code> \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c: \u0441 <code>SCons<\/code> \u0438\u043b\u0438 \u0441 <code>SNil<\/code>. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>refined<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>N<\/code>, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 <code>SList<\/code> \u043b\u0438\u0431\u043e \u0432 <code>SCons<\/code>, \u043b\u0438\u0431\u043e \u0432 <code>SNil<\/code>:<\/p>\n<pre><code class=\"scala\">transparent inline def refined: SCons[A, N - 1] | SNil.type =  inline if(constValue[N] == 0) SNil else this.asInstanceOf[SCons[A, N - 1]] <\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0435\u0449\u0435 \u0441 \u043f\u0430\u0440\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 Scala 3:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#inline-conditionals\" rel=\"noopener noreferrer nofollow\"><code>inline if<\/code><\/a> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0443\u0436\u043d\u0443\u044e \u0432\u0435\u0442\u043a\u0443 if.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 inline-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/docs.scala-lang.org\/scala3\/guides\/macros\/inline.html#transparent-inline-methods\" rel=\"noopener noreferrer nofollow\"><code>transparent<\/code><\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f &#171;\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u044d\u0442\u043e upper bound.<\/p>\n<\/li>\n<li>\n<p><code>A | B<\/code> &#8212; union-\u0442\u0438\u043f, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u0430\u043a \u0442\u0438\u043f <code>A<\/code>, \u0442\u0430\u043a \u0438 \u0442\u0438\u043f <code>B<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p><em>\u042f\u0432\u043d\u044b\u0439 \u043a\u0430\u0441\u0442 <\/em><code><em>this<\/em><\/code><em> \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 <\/em><code><em>else<\/em><\/code><em>-\u0432\u0435\u0442\u043a\u0435 \u043a\u0430\u043a <\/em><code><em>SCons[A, N - 1]<\/em><\/code><em>. \u041d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u043e\u0434\u0442\u0438\u043f <\/em><code><em>this<\/em><\/code><em>, \u0438 \u0435\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e <\/em><code><em>this<\/em><\/code><em>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 <\/em><code><em>SList[A, N]<\/em><\/code><em>.<\/em><\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>size<\/code> \u0438 <code>refined<\/code> \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0438\u0436\u0435. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f <code>refined<\/code> &#8212; \u043d\u0435 <code>SCons | SNil<\/code>, \u0430 <em>\u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439<\/em>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">\/\/ list: SList[Int, 2] = SCons(1,SCons(2,SNil)) val list = 1 :: 2 :: SNil  \/\/ val res0: Int = 2 list.size  \/\/ val res1: SCons[Int, 1] = SCons(1,SCons(2,SNil)) list.refined  \/\/ val nil: SList[Int, 0] = SNil val nil: SList[Int, 0] = SNil  \/\/ val res2: SNil.type = SNil nil.refined <\/code><\/pre>\n<h3>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f refined<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e <code>refined<\/code> \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c upper bound <code>refined<\/code> \u043a\u0430\u043a <code>SList[A, N]<\/code>: \u0442\u0438\u043f <code>SCons[A, N - 1] | SNil.type<\/code> \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u043c <code>SList[A, N]<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>N<\/code> (<code>N - 1<\/code> \u0438 <code>0<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e).<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 <code>SList[A, ?]<\/code>, \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>constVa<\/code><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-361234","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/361234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=361234"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/361234\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=361234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=361234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=361234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}