Scala 3.6.2ãåºãï¼ãã£ãã¼ï¼
Scala 3.6.2ã¯ãScala 3.6ç³»ã®æåã®æ£å¼ãªãªãªã¼ã¹ã§ãæ°å¤ãã®æ©è½ã追å ãããããã®è¨äºã§ã¯ãã®ãã¡ä¸»è¦ãªæ©è½ãç´¹ä»ãããã¾ããæ£ç¢ºããããåããããããåªå ãã¦ã¶ãã¯ãªæ¸ãã¦ããã¨ãããããã®ã§ãããããã¨ãã¯ãã³ã¡ãè¨äºã§è£è¶³ãã¦ããããã¨å¬ããã
- Scala 3.6.2ã使ã
- 3.6.0ã¨3.6.1ã¨ã®é¢ä¿
- Clause Interleaving (SIP-47)ã®å®å®å
- Givenã¨Context Boundsã®è¨æ³ã®æ¡å (SIP-64)
- Context Bounds for Polymorphic Functions
- Add an infix shorthand for Tuple.{Append, Concat}
- ã¾ã¨ã
Scala 3.6.2ã使ã
Scala CLIã§ã¯ã-S 3.6.2
ãªãã·ã§ã³ãã¤ããã¨ãã®ãã¼ã¸ã§ã³ã使ããã¨ãã§ãã:
% scala-cli -S 3.6.2
sbtã§ã¯ãscalaVersion
ã«3.6.2
ãæå®ãã¦ããã¨è¯ã:
lazy val root = (project in file(".")) .settings( name := "Hello", scalaVersion := "3.6.2" )
3.6.0ã¨3.6.1ã¨ã®é¢ä¿
Scala 3.6.2ã¯Scala 3.6ç³»ã®æåã®æ£å¼ãªãªãªã¼ã¹ã¨æ¸ãããã§ã¯3.6.0ã¨ã3.6.1ã¯ä½ãªã®ãã¨ããã¨ã
- ãªããã¹ãä½ãã§ä½æ¥ä¸ã®ãã¤ã«ã¹ãã¼ã³ããªã«ããpublishããã¦ãã¾ã£ãã®ã3.6.0(ãã£ã¡ããã¡ãã)
- ãããã«ãã®ã¾ã¾ã§ã¯ããºãã®ã§æä½éåãããã«hotfixãå½ã¦ãã®ã3.6.1
ã ã£ãããããæä½éã®hotfixãªã®ã§ãããã¯ã·ã§ã³ã§ã®å©ç¨ã¯å ¨ãæ¨å¥¨ããã¦ããããã¾ã 使ããªãã§ï¼ã¨ããã¹ãã¼ã¿ã¹ã«ãªã£ã¦ããã®ã ãããã¦ã¡ããã¨ãªãªã¼ã¹ã§ããç¶æ ã«ãªã£ã¦åºã¦ããã®ã3.6.2ã¨ããããã§ãåºæ¬çã«3.6.0ã¨3.6.1ã¯æ¬ çªæ±ãã
ããã§ã¯å種æ©è½ã«ã¤ãã¦è¦ã¦ãããã
Clause Interleaving (SIP-47)ã®å®å®å
Clause Interleavingã¨ããæ©è½ãå®å®ããã¨ã¿ãªãããexperimentalããæ¬ä½æ©è½ã«ææ ¼ãããã
Clause Interleavingã¨ã¯ãåãã©ã¡ã¼ã¿ãåå²ãã¦ãå¤ãã©ã¡ã¼ã¿ã¨äº¤äºã«(interleave)æ¸ããæ©è½ã
// Aã¨Bãåãããã¦ãã def pair[A](a: A)[B](b: B): (A, B) = (a, b)
ããããããã¾ã§ã®Scalaã§ã¯ãå¤ãã©ã¡ã¼ã¿ãªã¹ããåå²ã§ãã:
def plus0(x: Int, y: Int): Int = x + y plus0(42, 666) def plus(x: Int)(y: Int): Int = x + y plus(42)(666)
ãã©ã¡ã¼ã¿ãªã¹ããåå²ãããã¨ã§ãå¾ãã追å ã§ãã©ã¡ã¼ã¿ã渡ããã¨ãã§ããããã«ãªããä¾ãã°å
±éã®ãã©ã¡ã¼ã¿ãå
ã«æ¸¡ãã¦ãããæ®ã£ãé¢æ°ãmap
ã«æ¸¡ããããªå¦çã§é½åãè¯ãã£ã:
def withTax(tax: BigDecimal)(price: BigDecimal) = tax * price val withTax10 = withTax(BigDecimal("1.1")) // å ã«ç¨çã決ãã val prices = Seq(BigDecimal("1000"), BigDecimal("1999"), BigDecimal("500")) prices.map(withTax10) // mapã«æ¸¡ãã ãã§ãã // => List(1100.0, 2198.9, 550.0)
ããã¨åæ§ã«ãåãã©ã¡ã¼ã¿ãåå²ãã¦ãå¾ãã渡ãããããªä»çµã¿ã«ããããã¨ããã®ãClause Interleavingã
ãã®æ§æããã£ã¦å ·ä½çã«ä½ã便å©ã«ãªããã¨ããã¨ããã¹ä¾ååãã¤ã¾ãå¤ãã©ã¡ã¼ã¿ã«ä¾åãã¦åã決ã¾ããããªãã¿ã¼ã³ã§ä¾¿å©ã (ãªãªã¼ã¹ãã¼ã ããã®åã売ã):
trait Key { type Value } trait DB { def getOrElse(k: Key)[V >: k.Value](default: V): V // dependent type parameter }
ãããã©ããåãããªãå¤ãåãåºãã¨ãã«ããã©ã«ãå¤ãæå®ãããã¨ãããã¿ã¼ã³ãgetOrElse
ã ãããã®å¤ã®åãæ¢ã«åãã£ã¦ããã®ã§ã¯ãªãã¦ãKey
ã®ä¸ã«type Value
ããã£ã¦ãããå©ç¨ããªããã°ãªããªã(path-dependent)ãã¨ããã®ãä¸æ²ã®ã³ã¼ãã ãClause Interleavingã«ãã£ã¦V
ã®åãæå®ããã®ãk: Key
ã®å¾ãã«å»¶ã°ãã¦ããã®ã§ãV
åãç´ ç´ã«è¨è¿°ã§ãã¦ããã
åºæ¬çã«ãã®æ©è½ã¯ãå¾æ¥ã¯ãã³ãªãã¯ããã¯ã§è¨è¿°ãã¦ããããç´ ç´ã«æ¸ããããã«ãªã£ããç³»ã®æ©è½ã ã¨èãã¦ããã¨ããããã
Givenã¨Context Boundsã®è¨æ³ã®æ¡å (SIP-64)
Context Boundsã¨ããæ©è½ããããåºæ¬çã«åã¯ã©ã¹ã®ããã«ããæ©è½ã ã
ä¾ãã°ã以ä¸ã®ãããªãusing
ã(Scala 2ã§ã¯implicit val
ã)使ãã¡ã½ãããããã¨ãããusing
ãã¦ããåãF[åãã©ã¡ã¼ã¿ã§ä½¿ã£ã¦ãå]
ã®å½¢ã«ãªã£ã¦ããã®ããã½ã :
def max[A](xs: Seq[A])(using Ordering[A]) = ???
ãããã以ä¸ã®ããã«å: åã¯ã©ã¹
ã®ããã«æ¸ããæ©è½ãContext Boundsã :
def max[A: Ordering](xs: Seq[A]) = ???
ã¤ã¾ããdef foo[A](using F[A])
ã¨ããå½¢ã«ãªã£ã¦ããå ´åã¯def foo[A: F]
ã¨æ¸ãã¾ãããã¨ããã®ãContext Boundsã ããªãã§ãã®å½¢ã ãåªéãããã®ãã¨ããã¨ãåã¯ã©ã¹ãå©ç¨ããã¨ãã«ãããã®ãã¿ã¼ã³ã«ãªãããã ãä¾ãã°JSONã¨ã³ã³ã¼ãã欲ããã¨ãããã©ã³ã¶ã¯ã·ã§ã³ãããã¨ããã¢ãã¤ãã«ãªãã¨ããããããè¦æ±ã¯ããã¦ããã®å½¢ã«ãªãã
ãããããã¨A
ãäºåº¦æ¸ããªãã¦è¯ããªããã¹ãããªããè¦ãç®ã«ãªããé¢æ°ãèªãã¨ããããA
ããã£ã¦ãããã¯Ordering
ã«ãªããã¨ãã§ãã¦ãxs: Seq[A]
ããã£ã¦ã»ã»ã»ãã¨ããæãã§ç´ ç´ã«èªããã
ã¨ããã§ãContext Boundsã使ãã¨ããã§ã¯Ordering[A]
ã«ã¯ååãä»ããªãã®ã§ããã®ã¤ã³ã¹ã¿ã³ã¹ãå©ç¨ãããã¨ãã¯summon
ã§å¼ã³ä»ããå¿
è¦ããã:
def max[A: Ordering](xs: Seq[A]) = {
summon[Ordering[A]]
}
ããã ã¨æè§ã¹ãããªãããã®ãå¿ä½ãªããããã§SIP-64ã§ã¯ãContext Boundsã«as
ã¨ãã追å ã®æ§æã追å ãã:
def max[A: Ordering as o](xs: Seq[A]) = {
xs.reduce(o.max)
}
as
ãå©ç¨ããã¨ããã®åã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã«ååãä»ãã¦ããã«å©ç¨ã§ããããã«ãªããã¤ã¾ã以ä¸ã®æ§æã¨å
¨ãç価ã :
def max[A](xs: Seq[A])(using o: Ordering[A])
ããã ãã ã¨åã«åããã¨ãã§ããããã«ãªã£ãã ãã ããããSIP-64ã§ã¯åæã«è¤æ°ã®åã¯ã©ã¹ãæå®ããè¨æ³ã追å ããã:
def showMax[X : {Ord, Show}](x: X, y: X): String
ãã¡ãããåã ã®åã¯ã©ã¹ã«ååãä»ãããã¨ãã§ãã:
def showMax[X : {Ord as ordering, Show as show}](x: X, y: X): String = show.asString(ordering.max(x, y))
åºæ¬çã«ãã®æ©è½ã¯åã¯ã©ã¹ãæ´»ç¨ãã¦ããæã«é常ã«ä¾¿å©ã«ãªããã¨ããæãã®æ©è½ãªã®ã§ãæ®æ®µä½¿ã£ã¦ããªããã°ç¹ã«æ¶ããå¿ è¦ã¯ãªãã
Context Bounds for Polymorphic Functions
Polymorphic Functionsã§Context Boundsã使ããããã«ãªã£ãã
ããããPolymorphic Functionsã¨ã¯ãã¡ã½ããã§ã¯ãªãé¢æ°ã§ãåãã©ã¡ã¼ã¿ã使ããããã«ãªãã¨ããé常ã«ä¾¿å©ãªæ©è½ã§ããã
val pair = [A] => (a: A) => [B] => (b: B) => (a, b) val p = pair(10) p("foo") // => (10, "foo")
Scala 2ã§ã¯ãã®ãããªãã¨ã¯ã§ããªãã£ãã®ã§ãåãã©ã¡ã¼ã¿ãå©ç¨ããããã°def
ã使ã£ã¦ã¡ã½ããã¨ãã¦å®è£
ããå¿
è¦ããã£ãã
ããã¦ä»åPolymorphic Functionsã§Context Boundsã使ããããã«ãªã£ããã¤ã¾ã以ä¸ã®ãããªã³ã¼ããæ¸ããããã«ãªã£ã:
val showMax = [X : {Ord as ordering, Show as show}] => (x: X, y: X) => String => show.asString(ordering.max(x, y))
ããã«ããval
ã®æ©è½ãããdef
ã«è¿ã¥ãããã¾ããé¢æ°ã¯å¿åé¢æ°ã¨ãã¦ãã®å ´ã«æ¸ããã¨ãã§ããã®ã§ãå¿åé¢æ°ã渡ãããã¨ãã®è¡¨ç¾åãä¸æãããã¨ã«ãªãã
Add an infix shorthand for Tuple.{Append, Concat}
Tuple.Append
ã¨Tupple.Concat
åã«å¯¾ãã便å©ãªè¡¨è¨ã追å ãããã
ã¾ããScala 3ã§ã¯ã¿ãã«ã®æ±ããããæè»ã«ãªã£ã¦ãããã¨ã«çæãããããScala 2ã¾ã§ã§ã¯ã¿ãã«ã¯22-ã¿ãã«ã¾ã§ããä½ããã¨ãã§ããªãã£ãããScala 3ããã¯ç¡å¶éã¨ãªã£ããã¾ããæ°ãéãã¿ãã«ã¨ã®é¢é£æ§ãããæè»ã«å®ç¾©ãããã
def addOne[T <: Tuple](t: T) = 1 *: t
ä¾ãã°ä¸æ²ã®ãããªã¡ã½ããã¯ãã¿ãã«ã渡ãã¨å é ã«1ããã£ã¤ããæ°ããªã¿ãã«ãè¿ã:
addOne(EmptyTuple) // => (1) addOne((42, "foobar", false)) // => (1,42,foobar,false)
ã¾ããã®ä¾ã§ã®*:
ã¯ã¿ãã«ã®ã¡ã½ããã ããScala 3.6.2ã§ã¯ãåã¬ãã«ã§ã®è¡¨ç¾åã®ããã«:*
ã¨++
ãæ°ãã«Tuple.Append
ã¨Tuple.Concat
ã®ã¨ã¤ãªã¢ã¹ã¨ãã¦è¿½å ããã:
import Tuple.{:*} type SB = (String, Boolean) type SBI = SB :* Int // => (String, Boolean, Int)
ããã¯åã«åã¬ãã«ã®æä½ã便å©ã«ãªãããã¨ããæãã®æ©è½ã§ã使ããªã人ã¯ãããã使ããªãã¨æãã
ã¾ã¨ã
ä»ã«ãç´°ãããªæ©è½è¿½å ãä¿®æ£ã沢山ããããexperimentalãªæ©è½è¿½å ã ã£ããã³ã³ãã¤ã©å é¨ã®ä¿®æ£ã¨ããå¤ãã®ã§ããã§ã¯å²æããã