æ¡å¼µå¯è½ã¬ã³ã¼ãã®ã©ã¤ãã©ãªrecord4sã«ã¤ãã¦ScalaMatsuri 2024ã§çºè¡¨ãã¾ãã
ScalaMasturi 2024ã§, æä½ã®æ¡å¼µå¯è½ã¬ã³ã¼ãã®ã©ã¤ãã©ãªrecord4sã«ã¤ãã¦çºè¡¨ãã¦ãã¾ãã.
çºè¡¨ã§è§¦ããããªãã£ãç¹ãè£è¶³ããªãã, å 容ãæç« ã«ãã¦ãããã¨æãã¾ã. ã¨ãã«record4s以å¤ã®ã¬ã³ã¼ãå®è£ ã¨ã®æ¯è¼ã«ã¤ãã¦ã¯ãã®è¨äºã§ã®å®å ¨æ¸ãä¸ããã§ã.
- ã¢ããã¼ã·ã§ã³
- Scala 3ã®æ¨æºæ©è½ã«ãã解決
- çæ³
- record4s
- Tips
- å é¨å®è£
- Scalaã®ä»ã®ã¬ã³ã¼ãå®è£
- ä»ã®è¨èªã§ã®ä¾
- ããã©ã¼ãã³ã¹
- ã¾ã¨ã
ã¢ããã¼ã·ã§ã³
ãã¨ãã°, ææè¨äºãæ稿å¯è½ãªããã°ãµã¼ãã¹ãä½ã£ã¦ããã¨ãã¾ã. ããã¨ç¡æã®ããã°è¨äºã¨, ææé¨åãããããã°è¨äºããããã表ããã¡ã¤ã³ã¢ãã«ã欲ãããªãããã§ã. ä¼¼ããããªã¯ã©ã¹ãæ¸ããã¨ã«ãªãã¾ã. ä¸ã®ä¾ã§ã¯ææé¨åã®å
容ã表ãpaidPartOfBody
ã®æç¡ã ããç°ãªãã¾ã.
ç¡æè¨äºã¨å ±éããé¨åãå¼ãã¦ãã¦, ææé¨åã欲ããã¨ãã¯ãã£ã¡ãå¼ããªã©ããã¨, è©°ãæ¿ããå¿ è¦ã«ãªãããã§ã.
ããã«ä¸æ¸ãè¨äºãæ±ããããã«ãããã¨æã£ãã, ã¾ãåããããªã¢ãã«ãå®ç¾©ãããã¨ã«ãªãã¾ã.
ææã»ç¡æ, å ¬éã»ä¸æ¸ããåããå¿ è¦ã«ãªããã£ã¼ã«ãã追å ãããã¨æãã¨, ãã¹ã¦ã®å®ç¾©ãæ¸ãæããç¾½ç®ã«ãªãã¾ã. è©°ãæ¿ããã¦ãã¨ããããã¹ã¦ç´ãã¦åããªãã¨ããã¾ãã.
çºè¡¨ã§ã¯ãããããµãã«è©±ãã¾ããã, å人çã«ã¯ãã®ä¾ã®ããã°è¨äºã®ã¢ãã«ã¯ãããªã«ããã¨ã¯æãã, ãã®ããã§ã¢ããã¼ã·ã§ã³ã®å
±æã妨ããªããå°ãä¸å®ã§ãã. ã¨ã¯ãã, çºè¡¨å¾ã«吉村さんã¨è©±ãã¦ãã¦, ãããããã¨ã¯ãã¬ã¼ã³ãã¼ã·ã§ã³ã¢ãã«ãããã¯ãã¥ã¼ã¢ãã«ã¨ããã®ã, ããã¯ã¨ã³ãã§è¨ãã°APIã¨ãã¦è¿å´ãã¹ãå¤ã®ã¢ãã«ãå®ç¾©ããã¨ãã«ã¯æ¬å½ã«ããããã¨ãã話ã«ãªãã¾ãã. åèªèº«ãçµé¨ãããã¾ãã, XxWithYy
ã¿ãããªcase class
ãç¡éã«çãã¾ã. ããããä¾ã ã¨æã£ã¦è¦ã¦ãããã¨ãã£ããããããããªããã¨æãã¾ã.
Scala 3ã®æ¨æºæ©è½ã«ãã解決
Scala 3ã«ã¯構造的型の機能ããã, ãã(ã¨äº¤å·®å(intersection type))ã使ãã°éè¤ãªãåè¿°ã®ã¢ãã«ã®åãå®ç¾©ã§ãã¾ã.
ãã®ä¾ã«ããã
Model { val id: PostId val title: String val body: String }
ã®ããã«ãã£ã¼ã«ãåã¨ãã®åãval
ã§ç¾
åããã®ãæ§é çåã§ã. 1è¡ã§æ¸ãå ´åã¯Model { val id: PostId; val title: String; val body: String }
ã®ããã«;
ã§åºåãã¾ã.
ã¡ãªã¿ã«, Scala 2ã¾ã§ã®æ§é çåãç¥ã£ã¦ãã人ã®ããã«è£è¶³ãã¦ããã¨, Scala 3ã§ã¯æ§é çåã使ã£ã¦ããªãã¬ã¯ã·ã§ã³ã¯çºçããªããªãã¾ãã*1. å®å¿ãã¦ä½¿ãã¾ã.
ããã, åã¯ãã£ããæ¸ãã¦ãå¤ã®æ¸ãæ¹ãå¾®å¦ã«ãªãã¾ã.
æ§é çåã®å¤ãä½æããã¨ãã¯å·¦ã®ããã«æ¸ããã¨ã«ãªã, asInstanceOf
ãã¦ãããããã£ã¼ã«ãåãééãã¦ãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãã, å¾ããã¢ã¯ã»ã¹ããã¨ãã«å®è¡æã¨ã©ã¼ã¨ãªãã¾ã. åå®å
¨ããããã¨ãã¦ã¯çéã§ãã¾ãã. Option
ã«å¯¾ãã¦get
ããã®ã¨åããããã®ç½ªã§ã.
ã¾ã, ãã£ã¼ã«ãã追å ãããã¨æãã¨ã ãã¶ç¡çç¢çãªæãã«ãªãã¾ã(å³).
çæ³
çæ³ã¨ãã¦ã¯ãããªãµãã«æ¸ããã¨ããã§ãã.
ãã£ã¼ã«ãã®è¿½å ãããã ã¨å©ããã¾ã.
ãã, ãããªé½åããè¡ããããª. ãããã¤ã±ã¡ãããã§ã. ãã, record4sãªãã!
record4s
å®ã¯, ãçæ³ãã¨ãã¦æ¸ããä¾ã¯ã¨ã¤ãªã¢ã¹ãé©åã«è¨å®ããã¨ãã®ã¾ã¾åãã¾ã.
ããå°ãå
·ä½çã«ä½¿ãæ¹ãè¦ã¦ããã¨, %(...)
ã§ã¬ã³ã¼ããæ°è¦ã«ä½æã§ã, æ§é çåãä»ãã¾ã. ã¡ãªã¿ã«, %
ã¯ãªãã¹ãæåæ°çãã¬ã³ã¼ããä½ããããã«1æåã«ãã¦ãã, ãã®è¨å·ã¯Perlã®é£æ³é
åã®ã·ã¸ã«ã«ç±æ¥ãã¾ã.
å½ç¶ã§ãã, ã¡ããã¨åãä»ãã¦ããã®ã§åå¨ããªããã£ã¼ã«ãã«ã¯ã¢ã¯ã»ã¹ã§ãã¾ãã(æ£ããã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãã¾ã).
(è¤æ°)ãã£ã¼ã«ãã®è¿½å ãã§ãã¾ã.
2ã¤ã®ã¬ã³ã¼ãã®çµåãå¯è½ã§ã.
ãã£ã¼ã«ãã®æ´æ°ãã§ãã¾ã. ã¬ã³ã¼ãã¯ã¤ãã¥ã¼ã¿ãã«ãªã®ã§, åã«ãã£ã¼ã«ããç½®ãæãã£ãæ°ããã¬ã³ã¼ããä½ãããã ãã§ã. æ´æ°å¾ã®ãã£ã¼ã«ãã¯æ´æ°åã¨åãç°ãªã£ã¦ãã¦ãæ§ãã¾ãã.
ä»ã«ãæ©è½ãçãã ããã!
Tips
ã¡ã½ããã®å®ç¾©
æ¡å¼µã¡ã½ãããå®ç¾©ããã°, ã¬ã³ã¼ãã«å¯¾ãã¦ã¡ã½ãããå¼ã¶ãã¨ãã§ãã¾ã. ããå°ã詳ãã説æã¯こちら.
æ§é çåã«å¯¾ãã¦æ¡å¼µã¡ã½ãããå®ç¾©ããå ´å, ãã®é¨ååã«å¯¾ãã¦ãåãã¡ã½ãããå¼ã¹ããã, ãã£ã¼ã«ãã足ãã¦ããã®ã¾ã¾åãã¾ã. ãã®ä¾ã§ã¯BlogPost
ã«å¯¾ãã¦summary
ã¡ã½ãããå®ç¾©ãã¦ããã ãã§, paidPartOfBody
ãã£ã¼ã«ããå¢ããã ãã®BlogPostWithPaywall
ã«å¯¾ãã¦ãsummary
ãå¼ã¹ã¾ã.
ä¾ã使ã£ã¦JSONããã³ã¼ã
record4sã¨ã¯ç¡é¢ä¿ã«, ä¸è¬ã«JSONæååããã³ã¼ãããã¨ãã¯ãã³ã¼ãå
ã®åãæå®ããå¿
è¦ãããã¾ã. ãã³ã¼ãå
ãcase class
ãªãã¯ã©ã¹åãæ¸ãã ãã§æ¸ã¿ã¾ãã, ãã³ã¼ãå
ãæ§é çåã ã¨å°ãé¢åã§ã. % { val name: String; val age: Int }
ã¿ãããªåãé·ã
ã¨æ¸ããã¨ã«ãªãã¾ã.
ããããã¨ã, 以ä¸ã®decodeByExample
ãå®ç¾©ãã¦ããã¨, ã¤ã³ã¹ã¿ã³ã¹ä¾ã使ã£ã¦ãã³ã¼ãå
ã®åãæ¨è«ã§ãã¾ã.
OpenAPIã使ã£ã¦ããå ´åãªã©, ã ãããä¾ã¯æ¸ãã¨æãã¾ãã, ããã§ãªãã¨ããããã¯ããããæ§é ã®JSONã«ãªã£ã¦ãæ³å®ãã¨ããã®ãæ¸ãã¦ããã¨åãããããã¯ããªã®ã§, ãªã¹ã¹ã¡ã®ããæ¹ã§ã*2.
å é¨å®è£
ãã£ã¼ã«ãã¢ã¯ã»ã¹
æ¨æºã©ã¤ãã©ãªã®Selectable
ã使ããã¨ã§, Scala 3ã³ã³ãã¤ã©ã«ãã£ã¦ãã£ã¼ã«ãã¢ã¯ã»ã¹ã¯selectDynamic
ã®å¼ã³åºãã«ç½®æããã¾ã.
ãã®ä»çµã¿ã¯Dynamic
ã«ä¼¼ã¦ãã¾ãã, Selectable
ã¯éçã«è§£æ±ºå¯è½ãªå ´åã®ã¿è¨±ããã, ããã ãã§å®å
¨ãªãã£ã¼ã«ãã¢ã¯ã»ã¹ãæä¾ã§ãã¾ã.
ã¬ã³ã¼ãã®çµå
å
é¨çã«ã¯ã¬ã³ã¼ãã®çµåã¯Map
ã®çµåã§ã. ã¬ã³ã¼ãã«å¯¾ãã¦++
ãconcat
ãå¼ã¶ã¨Map
ãçµåãã¦æ°ããªã¬ã³ã¼ããä½ãæä½ã«å¤æããã¾ã.
è¿ãå¤åã¯Concat
ã¨ããåã®given
ã¤ã³ã¹ã¿ã³ã¹ãæ¢ç´¢ãã¦æ±ºããããã«ãªã£ã¦ãã¾ã. æ§é çåãåã¬ãã«è¨ç®ã§çæããæ¹æ³ã¯ç¾ç¶(Scala 3.3.3æç¹)ã¯åå¨ããªããã, given
ã®æ¬ä½ããã¯ãã«ãããã¨ã§ã³ã³ãã¤ã«æã«æ§é çåã®çµåãè¨ç®ãã¦ãã¾ã. æ§é çåã®çµåã¯äº¤å·®åã§ããã¨æãããããã¾ããã, ããã ã¨åããã£ã¼ã«ãåã®å¥ã®åãããããã®ã¬ã³ã¼ãã«ããå ´åã«ããããªãã¨ã«ãªãã¾ã.
éè¤ãã¼åé¡
å®ã¯åç¯ã®ã¬ã³ã¼ãçµåã®å®ç¾©ã«ã¯åé¡ãããã¾ã. åãç°ãªãåãååã®ãã£ã¼ã«ããæã¤ã¬ã³ã¼ãã2ã¤ãã, å¾è ã®éçåã§ã¯ãã®ãã£ã¼ã«ãã®åå¨ãé ããå ´å, ãã£ã¼ã«ãã®åã¨å¤ã®ä¸ä¸è´ãçºçããããã¨ãå¯è½ã§ã.
ãã®ä¾ã§ã¯, r1.age
ã¯Int
ã§r2.age
ã¯String
ã§ãã, r2
ã®åã{ val name: String }
ã«ã¢ãããã£ã¹ããã¦ããã¨, (r1 ++ r2).age
ã®åã¯Int
ã«, å¤ã¯String
ã«ãªã£ã¦ãã¾ãã¾ã.
{ val age: Int }
ã¨{ val name: String }
ãåã¬ãã«ã§çµåããã¨{ val age: Int; val name: String }
ãªã®ã«å¯¾ã, Map("age" -> 3).concat(Map("name" -> "tarao", "age" -> "unknown"))
ã¯Map("age" -> "unknown", "name" -> "tarao")
ã«ãªãããã§ã.
ãã®ãã, ã¬ã³ã¼ãã®çµåã¯åç´ãªMap
ã®concat
ã§ã¯ãã¡ã§, å³è¾ºã®ã¬ã³ã¼ãã¯éçåã«è¡¨ãããã£ã¼ã«ãã®ã¿ã«çµãå¿
è¦ãããã¾ã.
Scalaã®ä»ã®ã¬ã³ã¼ãå®è£
çºè¡¨ã§ã¯è§¦ãã¾ããã§ããã, æ¡å¼µå¯è½ã¬ã³ã¼ããScalaã§å®è£ ãã/å®è£ ãããã¨ããä¾ã¯ããã¤ãããã¾ã. record4sã®å®è£ ã«ããã£ã¦ã大ãã«åèã«ãã¦ãã¾ã.
shapelessã®Record
shapelessã«ã¯Record
ããã, ããã¯å®ã¯æ¡å¼µå¯è½ã¬ã³ã¼ãã§ã. ãã ã, æ§é çåã§ã¯ãªãHList
ãç¨ããé£æ³é
åã§å®ç¾ãã¦ãããã, ãã£ã¼ã«ãã®é åºãç°ãªãã¨å¥ã®åã¨è¦ãªãã, ã¾ããµã¤ãºã大ãããªãã¨ãã£ã¼ã«ãã¸ã®ã¢ã¯ã»ã¹ãæ´æ°ãã©ãã©ãé
ããªãã¾ã(å¾ã»ã©ãã³ããã¼ã¯ã®ã°ã©ãã§è¦ã¾ã). ã¬ã³ã¼ãã®åãèªã¿ã«ããæ¸ãã®ãããªã大å¤ã§ã.
scala-records
scala-recordsã¯ããæå³record4sã®ç´æ¥ã®ç¥å
ã¨è¨ãã¾ã. ããã¯Scala 2åãã«ã¬ã³ã¼ãåãæä¾ãããã®ã§, æ§é çåã§ã¬ã³ã¼ãåã表ç¾ãã¾ã. record4sã¨åæ§ã«å
é¨å®è£
ã¯Map
ã«ãªã£ã¦ãã¦, Map
ã®æä½ããã¯ãã§é è½ãããã¨ã§åå®å
¨ã«ã¬ã³ã¼ãã®æä½ãã§ããããã«ãªã£ã¦ãã¾ã. ãã ã, æ¡å¼µå¯è½ã§ã¯ããã¾ãã.
å®ã¯, scala-recordsãæ¡å¼µå¯è½ã¬ã³ã¼ãã«ãã試ã¿ãããã¾ãã:
#104 Introduce a merge
operation for joining two records.
å人çã«ãã®è°è«ã¯ãã£ã¨è¿½ãããã¦ãã¦æ©è½è¿½å ãå¿å¾ ã¡ã«ãã¦ããã®ã§ãã, ãã£ãããå®è£ ãããªãã¾ã¾ã§ãã. ãããããã¦ãããã¡ã«Scala 3ããªãªã¼ã¹ãã, scala-recordsã§ã¯ããªã大å¤ãªãã¯ãã§å®ç¾ãã¦ããé¨åãã ãã¶ç°¡åã«å®è£ ã§ããããã«ãªã£ããã, scala-recordsã«ä¹ã£ããããä¸ããScala 3ã§æ¸ããæ¹ãæ©ãã¨å¤æãã¦, 諦ãã¦èªåã§å®è£ ããã®ãrecord4sã§ã. å¾ã£ã¦record4sã¯, scala-recordsãæ¡å¼µå¯è½ã«ãããã¨ããã¨ãã®è°è«ã, scala-recordsãshapelessã®ã¬ã³ã¼ããæèãã¦ããã©ã¼ãã³ã¹ã«é¢ãã¦é æ ®ãã¦ããé¨åããã¹ã¦è¸è¥²ããä¸ã§å®è£ ãã¦ãã¾ã.
Karlsson & Haller '18
Scalaã§æ¡å¼µå¯è½ã¬ã³ã¼ããå®ç¾ããæ¹æ³ã«ã¤ãã¦ã¾ã¨ããè«æãããã¾ã.
Extending Scala with Records: Design, Implementation, and Evaluation.
Olof Karlsson and Philipp Haller.
In Proceedings of the 9th ACM SIGPLAN International Symposium on Scala, New York, NY, 2018.
ãã®è«æã§ã¯shapelessãscala-recordsã§ã®å®ç¾æ¹æ³ã«å ã, ãã®è«æç¬èªã®æ¹æ³ãææ¡ããä¸ã§, åææ³ã®ç¹å¾´ãæ¯è¼ãã¦ãã¾ã. ãã®è«æã®ææ¡ææ³ã§ã¯implicit
ãã©ã¡ã¼ã¿ã«ãã£ã¦è¿ãå¤åãè¨ç®ãã¦ãã¦, ããã¯record4sã§ããã£ã¦ããããæ¹ã§ã*3. ãã ã, ãã®è«æã§ã¯ããã¾ã§Scalaã³ã³ãã¤ã©ãæ¡å¼µããåæã®ãã, implicit
ã«è¦æ±ããåã¯çµã¿è¾¼ã¿ã®åã§ãã, ã³ã³ãã¤ã©ãç¹å¥æ±ãããããã«ãªã£ã¦ãã¾ã. ããã, given
ããã¯ãã«ãããã¨ã§ã³ã³ãã¤ã©ã«æãå
¥ããã«å®ç¾ãã¦ããã®ãrecord4sã§ã.
ã¾ã, ãã®è«æãæ¸ãããå½æScala 3ã®å®è£ ã¯ããç¨åº¦é²ãã§ãã¦, ææ¡ææ³ãScala 3ã³ã³ãã¤ã©ãæ¹é ãã¦å®è£ ããã¾ããã, è¨è¨ã«ã¯Scala 2æ代ã¾ã§ã®èª²é¡ã大ããåæ ããã¦ãã¾ã£ã¦ãã¾ã. Scala 2ã§ã¯whiteboxãã¯ãã使ãã¨IDEä¸ã§ãã¾ãåæ¨è«ãããã³ã¼ããçã£èµ¤ã«ãªã£ã¦ãã¾ãã. ãã®ããææ¡ææ³ã§ã¯æ¥µåwhiteboxãã¯ãã使ããªãããã«ãªã£ã¦ãã, ãã®å¶ç´ã®ããã«ãã£ã¼ã«ãã®è¿½å ã1度ã«1ã¤ããã§ãã¾ãã(è¤æ°ãã£ã¼ã«ããã¾ã¨ãã¦æå®ãã¦åæåãããã¨ãã§ãã¾ãã).
Scala 2ã®whiteboxãã¯ãã«ç¸å½ããScala 3ã®transparent inline
ãã¯ãã¯ã ãã¶æ¹åããã¦ãã, ãã®ç¹ãæ°ã«ããå¿
è¦ã¯ãªããªãã¾ãã. ããããrecord4sã§ã¯è¤æ°ãã£ã¼ã«ãã¾ã¨ãã¦è¿½å ã§ããããã«ãªã£ã¦ãã¾ã. ãã®ä»£ãã, record4sãScala 2ããµãã¼ããããã¨ã¯ããã¾ãã*4.
ãã®è«æã§ã¯åå®è£ ã®ããã©ã¼ãã³ã¹ã®æ¯è¼ãããã¦ãã¦, record4sのベンチマークテストããã®è«æã§ç¨ããããææ¨ãåæã¨ãã¦ãã¾ã(ãã以å¤ã®ææ¨ãå ãã¦ãã¾ã).
record4sã®ArrayRecord
record4sã§ã¯ããã©ã¼ãã³ã¹ç¹æ§ã®ç°ãªãArrayRecord
ã¨ããã¯ã©ã¹ãæä¾ãã¦ãã¾ã.
shapelessã®ã¬ã³ã¼ãã«ã¯è¯ãç¹ããã, ããã¯ã¬ã³ã¼ãã®åæåãçµåã®å®è¡é度ãé«éãªãã¨ã§ã. ãã®ç¹æ§ã«å ãã¦ãã£ã¼ã«ãã¢ã¯ã»ã¹ã®å®è¡æéãã¬ã³ã¼ãçµåã®ã³ã³ãã¤ã«æéãæããã®ãArrayRecord
ã§ã. ãã ã, shapelessåæ§, ãã£ã¼ã«ãã®é åºãæ¿ããã¨å¥ã®åã¨è¦ãªãã, æ§é çåã§ã¯ããã¾ãã. ã¬ã³ã¼ãåã®æ¸ãæ¹ãããç
©éã§ã.
ArrayRecord
ã¯ãã®åã®éãå
é¨ã®ãã¼ã¿è¡¨ç¾ãMap
ã§ã¯ãªãé
åçãªãã®(å®éã¯Vector
)ã«ãªã£ã¦ãã¾ã. åãã£ã¼ã«ãã¸ã®ã¢ã¯ã»ã¹ã¯ã³ã³ãã¤ã«æã«é
åè¦ç´ ã¸ã®ã¤ã³ããã¯ã¹åç
§ã«ç½®æããã¾ã.
Named Tuples
Scala 3.5ã«ã¯å®é¨çæ©è½ã¨ãã¦Named Tuplesã追å ããã¾ã. (name = "tarao", age = 3)
ãªã©ã¨ããã¨(name: String, age: Int)
åã®ååä»ãã®ã¿ãã«ãä½ããæ©è½ã§ã. ãã®ååã¯åã¬ãã«ã«ã®ã¿åå¨ãã¦ãã¦, å®è¡æã«ã¯æ¶å»ããã¦ãã, å®ä½ã¯æ®éã®ã¿ãã«ã§ã.
ã¡ããã©, ãã¡ãã®è¨äºã§ãã¯ãã®ä¾é¡ã¨ãã¦ä½¿ã£ãNamedArray
ã, å®ä½ãã¿ãã«ã§ã¯ãªãIndexedSeq
ã«ãã¦åããããªãã¨ããã£ã¦ãããã®ã«ãªãã¾ã:
Named Tuplesã¯, shapelessã®ã¬ã³ã¼ããArrayRecord
ã¨åæ§ã«, ãã£ã¼ã«ãã®é åºãæ¿ããã¨å¥ã®åã¨è¦ãªããã¾ã. ããã©ã¼ãã³ã¹ç¹æ§ãããããArrayRecord
ã«è¿ããã®ã«ãªãã¨æãã¾ã. ãã ã, ArrayRecord
ã¯case class
ã¨åçã®Product
ã®ã¤ã³ã¿ãã§ã¼ã¹ãå®è£
ããããã«ãã£ã¼ã«ãåããã¼ã¿ã¨ãã¦æã£ã¦ãã, ã¡ã¢ãªå¹çã¯Named Tuplesã®æ¹ããããªãã¾ã. ãã®ä»ã®ç¹æ§ã§ã¯ããããNamed Tuplesã¨ArrayRecord
ã¯åçã§, åºå®ã®ãã£ã¼ã«ãåã ãã使ãå ´åã¯Named Tuplesãé©ãã¦ãã¾ãã, ãã£ã¼ã«ãã®è¿½å ã»å¤æ´ãããããå ´åã¯record4sã®%
ã®æ¹ãé©ãã¦ãã¦ããã¯ãã§ã.
Named Tuplesãæ£å¼ãªè¨èªæ©è½ã¨ãã¦æ¡ç¨ãããã°, ArrayRecord
ã®å½¹ç®ã¯ã»ã¼ãªããªã*5ãã, record4sããåé¤ãã(ãããã¯Named Tuplesã®ã©ããã¼ã«ãã)ã¤ããã§ã.
ä»ã®è¨èªã§ã®ä¾
PureScript
è¨èªã«çµã¿è¾¼ã¿ã§æ¡å¼µå¯è½ã¬ã³ã¼ããå®è£
ããã¦ããä¾ã¨ãã¦ã¯PureScriptãããã¾ã:
documentation/language/Records.md at master · purescript/documentation
å®éã«ã©ãå®è£ ããã¦ããã®ãã¯ç¥ãã¾ããã, PureScriptã¯altJSãªã®ã§è£å´ã¯JavaScriptã®ãªãã¸ã§ã¯ãã«ãªã£ã¦ããã¨ããã¨, ãã£ã¼ã«ãã¢ã¯ã»ã¹ãé«éã«ã§ãããã§ã.
TypeScript
æ¡å¼µå¯è½ã¬ã³ã¼ããã©ããããã®ããè¦ã¦ãããTypeScriptã§ã§ããããã¨æã£ã人ãããããããã¾ããã, æ®å¿µãªããããã¯æ©è¨ã§ã. TypeScriptã®å ´åã¯ãéè¤ãã¼åé¡ããçºçããããã§ã.
const r1: { age: number } = { age: 3 }; const p: { name: string, age: string } = { name: "tarao", age: "unknown" }; const r2: { name: string } = p; const r = { ...r1, ...r2 }; const age: number = r.age; console.log(age);
"unknown"
æ¬æ¥ã¯const age: number = r.age;
ã®è¡ã§ã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªã£ã¦ã»ããã§ãã, ç´ éããã¦ãã¾ã£ã¦ãã¾ã. TypeScriptãåå®å
¨ã§ã¯ãªãè¦ç´ ã¯ä»ã«ãããããããã¾ãã, ãããç°¡åã«åå®å
¨æ§ãç ´å£ã§ãã¦ãã¾ãã®ã¯é©ãã§ã. ããã§ã¯æµç³ã«ãæ¡å¼µå¯è½ã¬ã³ã¼ããå®ç¾ã§ãã¦ãããã¨ã¯è¨ããããã¨æãã¾ã.
TypeScriptã«æ¡å¼µå¯è½ã¬ã³ã¼ãç¸å½ã®ä½¿ãæ¹ãæå¾
ãããªã, ã¹ãã¬ããæ§æ(ãObject.assign
)ã§ã¬ã³ã¼ããçµåããã®ãå°å°ãã¦, { ...r1, f1: v1, f2: v2}
ã®å½¢ã®ã¿è¨±ãããã«å¶éããå¿
è¦ãããã¾ã. (ã§ã¯linterã§ãããå¶éããã°ããã§ãããã¨è¨ãã¨, ã¬ã³ã¼ãã®çµåãã§ããªããããæ¡å¼µå¯è½ã¬ã³ã¼ããå®ç¾ãã¨ããæå³ã§ã¯çæè½ã¡ã ã¨æãã¾ã.)
Haskell
Haskellã«ã¯æ¡å¼µå¯è½ã¬ã³ã¼ãã®ã©ã¤ãã©ãªãããã¤ãããã¾ã:
Extensible record - HaskellWiki
ãã¾ã詳ããç¥ããªãã®ã§ã©ããã©ãããç¹å¾´ãã¨ããã®ã¯ããç¥ãã¾ãã. ãã , ã¬ã³ã¼ãåã¯ã©ã®è¨èªã§ãè¨æ³ãç¬ç¹ã«ãªããã¡ãªä¸, Haskellã¯ã¨ãã«è¨å·ãã©ãããæå³ã§ä½¿ãããããã£ããè¦ããªãã¨ä½¿ããªãå°è±¡ãããã¾ã.
ããã©ã¼ãã³ã¹
record4sã¯ããã©ã¼ãã³ã¹ã«ã¤ãã¦ãååã«æ°ãã¤ãã£ã¦ãã¾ã. 詳細ã¯こちらãè¦ã¦ãã ãã. ããã§ã¯çºè¡¨ã§ç´¹ä»ããé¨åã ã触ãã¦ããã¾ã.
ã¬ã³ã¼ãä½æã®å®è¡æé
ã¬ã³ã¼ãã®ä½æã«ãããæéã¯ãµã¤ãºã大ãããªãã«ã¤ãã¦ç·å½¢ã«å¢ãã¾ã. Map
ã¨åãã§ã.
ä¸æ¹, ArrayRecord
ãshapelessã®ã¬ã³ã¼ãã¯ä½æã®å®è¡æéã¯çãæ¸ã¿ã¾ã. ããã·ã¥ãããã®ããã·ã¥å¤ãè¨ç®ããå¿
è¦ããªãããã§ã.
ãã£ã¼ã«ãã¢ã¯ã»ã¹ã®å®è¡æé
ãã£ã¼ã«ãã¢ã¯ã»ã¹ã«ãããæéã¯ãã£ã¼ã«ãã®ã¤ã³ããã¯ã¹ãã¬ã³ã¼ãã®ãµã¤ãºã«ããã¾ãã. ããã·ã¥å¤ã®è¨ç®ã§ä¸ä¸ã¯ãã¾ãã, å®è³ªå®æ°æéã§ã. shapelessã®ã¬ã³ã¼ãã ã¨ãã£ã¼ã«ããåããé ã«æ¢ç´¢ããããç·å½¢æéããã£ã¦ãã¾ãã®ã¨ã¯å¯¾ç §çã§ã.
ã¬ã³ã¼ãçµåã®ã³ã³ãã¤ã«æé
ã°ã©ãããã¯å°ãèªã¿åãã¥ããã§ãã, Scala 3ã³ã³ãã¤ã©èªä½ã®æ§é çé¨ååã®æ¤æ»ãã«ãªã£ã¦ãããã, ã¬ã³ã¼ãçµåã®ã³ã³ãã¤ã«æéã¯ãµã¤ãºã®2ä¹ã«æ¯ä¾ãã¾ã. ãããshapelessã®ã¬ã³ã¼ãã¨æ¯ã¹ãã¨ãã£ã¨ã¾ãã§ã.
ãã³ããã¼ã¯ã®å®è£
åºæ¬çã«JMHã§è¨æ¸¬ã, Seabornã§å¯è¦åãã¦ããã ãã§ã. è¨æ¸¬å¯¾è±¡(shapelessãscala-records)ã®Scalaãã¼ã¸ã§ã³ãåããå¿ è¦ãããããScalaã®ãã¼ã¸ã§ã³ãã¨ã«sbtããã¸ã§ã¯ããåãã¦ãã¾ã.
[Karlsson & Haller '18]のベンチマーク実装ããã®ã¾ã¾ä½¿ããã¨ããã£ãã®ã§ãããã®ã¾ã¾ã§ã¯ãã«ãã§ãã, å¤ã«ã³ã¼ãçæãã¦ãã¦ä½ãè¨æ¸¬ãã¦ããã®ããåããã«ããã£ããã, ç´ æ´ãªã³ã¼ãã§åå®è£ ãã¦ãã¾ã.
Scala 2ãScala 3ã, ã³ã³ãã¤ã©ãã©ã¤ãã©ãªã¨ãã¦å¼ã³åºããã¨ãå¯è½ã§, ã³ã³ãã¤ã«ãããã³ã¼ãããå¼ã³åºãå ã®ã¯ã©ã¹ãã¡ã¤ã«ã«ã¢ã¯ã»ã¹ãã(例)ãã¨ãå¯è½ãªãã, ç¹å®é¨åã®ã³ã³ãã¤ã«ã«ãããæéãè¨æ¸¬ããã®ãé常ã«ãããããã£ãã§ã.
ãã³ããã¼ã¯ã«é¢ããã³ã¼ãã¯ä»¥ä¸ã«ããã¾ã.
ã¾ã¨ã
- record4sã¯Scala 3ã§æ¡å¼µå¯è½ã¬ã³ã¼ããæä¾ããã©ã¤ãã©ãª
- ã¢ããªã³ã°ã«ããã¦æç¨ãªå ´åããã
- ãã¯ãã¨ã¤ã³ã©ã¤ã³ã®æ©è½ã使ã£ã¦æ³¨ææ·±ãè¨è¨ããã¦ãã
- ããã¾ã§ã®ã¬ã³ã¼ãå®è£ ããµã¾ããè¨è¨ã«ãªã£ã¦ãã
- ããã©ã¼ãã³ã¹ã«ã¤ãã¦ãååã«é æ ®ããã¦ãã
*1:ããæ£ç¢ºã«è¨ãã¨, ãªãã¬ã¯ã·ã§ã³ãç¨ãããã®ã¯æ§é çåãã®ãã®ã¨ã¯å¥ã®ä»çµã¿ã«åãé¢ããã¾ãã.
*2:ãã®ããæ¹ã¯id:Windymeltããã«ãåãæ¸ãã®ã¯é¢åã ããã¤ã³ã¹ã¿ã³ã¹ããæ¨è«ããæ¹æ³ã¯ãªãããã¨è¨ããã¦æãã¤ãã¾ãã.
*3:shapelessã§ãé »åºã®ããããææ³ã§ã¯ããã¾ã.
*4:ãããããããããscala-recordsãæ¡å¼µå¯è½ã«ãã試ã¿ãé²ã¾ãªãã£ãä¸çªã®çç±ããããã¾ãã.
*5:ãã¨ãã¨ã¯JSONã«å¤æããé½åä¸, Productã®ã¤ã³ã¿ãã§ã¼ã¹ãåããã¬ã³ã¼ãåãããã¨é½åãããã£ãããã«å®è£ ãããã®ã§ããã, Productãä»ããªãå¤æãå¾ããå®è£ ããããä¸è¦ã«ãªã£ã¦ãã¾ãã. ããã©ã¼ãã³ã¹ç¹æ§ã¨ãã¦%ã¨ã¯éã£ãå©ç¹ããã£ãããæ®ãã¦ãã£ãã®ã, Named Tuplesã®ç»å ´ã§ããããæ¬å½ã«ä¸è¦ã«ãªãã¨ãããã¨ã§ã.