ã³ã³ãã¤ã«æè¨ç®ã§ã©ã ãè¨ç®ã®æ§æ解æå¨ã»è©ä¾¡å¨ã»åæ¨è«å¨ãå®ç¾ (Scala 3ç·¨)
ã¾ãã. ã¾ããªã®ã. ä½åç®ã . ã¨ãããã¨ã§, ã©ã ãè¨ç®ã®ã¤ã³ã¿ããªã¿ã®å®è£ ã¨ãã¦ã¯4åç®ããã*1, ã³ã³ãã¤ã«æè¨ç®ã§ãããã®ã¨ãã¦ã3åç®ãããã«ãªã£ã¦ãã¾ããã©, ã©ã ãè¨ç®ã®å¦çç³»ãã¾ãæ¸ãã¦ãã¾ã£ã.
ä»åã®ç®çã¯, Scala 3ã«ã¯match typesã¨ããæ©è½ããã, ããã ãã§ãã¥ã¼ãªã³ã°å®å ¨ãªã®ã§ã¯ãªãã, ã¨ããã®ãæ¤è¨¼ãããã. ã¾ã, æååãªãã©ã«åãæä½ããåã¬ãã«é¢æ°ã3.1.2-RC1ã«ãã¦ãã¦, ããã使ãã°æ§æ解æå¨ã ã£ã¦æ¸ãã.
çµç·¯
ãã¨ãã¨ã¯, id:xuweiãããæååãªãã©ã«åã§ã³ã³ãã¤ã«æã«åä½ããæ§æ解æå¨ãå®è£ ãã¦ããã®ãå§ã¾ã.
ããã§ã¯è¶³ãå¼ããããããã®ç°¡åãªå¼ã®è©ä¾¡å¨ããå®è£ ãã¦ããªãããã©, å²ã¨ãªãã§ãã§ãã¦ãã¾ãããã«è¦ãã.
experimental annotationå¿ è¦ã¨ã¯ãããããmatch typeãTuring-completeã«ãªã£ãå¯è½æ§ãããã¨æãã®ã ããã©ã
— Kenji Yoshida (@xuwei_k) 2022å¹´3æ1æ¥
Scala 3ã¯2ã¨éã£ã¦type systemã¯Turing-completeã§ã¯ãªãã!
ã¨ããã®ãæèãã¦ãã¯ãã ãã©ãããã¯ãããã§ããï¼
ã¨ãã話é¡ã誰ãâ¦
match typesã¯å帰ãã§ããã£ã½ãã®ã§, ã¾ããã¶ãæ®éã«ãã¥ã¼ãªã³ã°å®å ¨ã«ãªã£ã¦ããªããã¯, ã¨ããã®ã¯æè¦ã¨ãã¦ããã£ã¦ãããã©, ãã®ã¨ãã¯ã¾ã ããµã¼ãããããã§ã¹ã«ã¼ãã¦ãã.
ãããã¦ããã吉村さんãmatch typesã§æ£è¦è¡¨ç¾ã¨ã³ã¸ã³ãå®è£ ãã¦ãã¦,
ãªããããã¯ããåãã©ã ãè¨ç®ã®å¦çç³»ãæ¸ããªãã¨ãããªãæµããªã®ã§ã¯ãªãã, ã¨ããæãããã¦ãã.
éå»ã®äºä¾
Scala 2ã®åã·ã¹ãã ã¯ãã£ãããã¥ã¼ãªã³ã°å®å ¨ã«ãªã£ã¦ãããã, ã©ã ãè¨ç®ã®è©ä¾¡å¨ãå®è£ å¯è½. å®éã«ãã£ã¦ãã人ããã. åã§ã. Scalaãæ¸ãå§ãã¦1ã¶æã ã£ããã©, ããã§Scalaã®åã·ã¹ãã ã¸ã®ç解ãæ·±ã¾ã£ã.
ãã , Scala 2ã ã¨ãã¿ã¼ã³ããããç¹æ®å½¢å¼ã®æ¡ä»¶åå²ããªã, å帰ãããªãçã®ããããæ¹ã§ããã§ããªã*2. æ°å¤ãªãã©ã«åããªããã, ペアノの公理に沿って自分で自然数を定義ãããã¨ã«ãªã.
C++ã ã¨ããå°ãã¹ãã¬ã¼ãã«ã§ãã¦, ãã¿ã¼ã³ãããã¨å帰ã®ããé¢æ°åè¨èªãåã¬ãã«ã§åå¨ãã¦ãããããªæãã«ãªã£ã¦ãã. æ§æã¯ããªãããã¥ãããã©. ãããå®éã«ãã£ã¦ãã人ããã. åã§ã.
ãã®ã¨ãã¯C++03ã§ãã£ã¦ããã®ã§, æè¿ã ã¨ãã£ã¨ãã£ã¨æ¸ããããã¨æã. C++03ã®å ´åã¯ä»¥ä¸ã®ãããªæãã ã£ã.
é¢æ°ã¨è¿ãå¤
ãã³ãã¬ã¼ãã¡ã¿ããã°ã©ãã³ã°ã§ã¯ãã³ãã¬ã¼ãã¯ã©ã¹ãé¢æ°ã ã¨æã£ã¦ä½¿ã. ããã¦è¿ãå¤ã¯
typedef
ãã¦è¿ã. ãã¨ãã°ä»»æã®åS
,T
ãåãåã£ã¦åè ãè¿ãé¢æ°first
ã¯template<typename S, typename T> struct first { typedef S return_value; };ã®ããã«æ¸ãã. 使ãå´ã¯
class A {}; class B {}; typedef first<A,B>::return_value a;ã®ããã«ãããã¨ã§, è¿ãå¤ã
a
ã¨ããååã§åãåã.
ãã¿ã¼ã³ãããã¨å帰å¼åºã
ãã³ãã¬ã¼ãã®ç¹æ®åæ§æã使ãã¨, é¢æ°(ã ã¨æã£ã¦ãããã®)ã®å¼æ°ããã¿ã¼ã³ãããã§ãã. ããã«é¢æ°(ã ã¨æã£ã¦ãããã®)ã®å帰å¼åºããã§ãã.
struct nil {}; template<typename car, typename cdr> struct cons {}; template<typename list> struct length { // ããã©ã«ãã±ã¼ã¹ }; template<> struct length<nil> { // å¼æ°ã®å½¢ãnilã ã£ãã¨ã static const int return_value = 0; }; template<typename head, typename rest> struct length< cons<head,rest> > { // å¼æ°ã®å½¢ãcons<head,rest>ã ã£ãã¨ã static const int return_value = length<rest>::return_value + 1; }; length<nil>::return_value; // 0 length<cons<A,cons<B,cons<C,nil> > > >::return_value; // 3 length<A>::return_value; // ã³ã³ãã¤ã«ã¨ã©ã¼ (ããã©ã«ãã±ã¼ã¹ã§ã¯return_valueã¯æªå®ç¾©ã®ãã)
Scala 3ã®åã¬ãã«è¨èª
match types
Scala 3ã®match typesã¯ã ãããC++ã¨åãã§, ãããæ§æã¯ã ãã¶ãããããã. ä¸ã®C++ã§ã®ä¾ãScalaã§æ¸ãã¨ãããªã.
type First[S, T] = S trait A trait B summon[First[A, B] =:= A] // summon ã¯æå®ããåã® implicit å¤ã解決ããã¡ã½ãã // =:= ã¯ä¸¡è¾ºã®åãçããã¨ãã« implicit å¤ãå¾ããããããªå // (ã¤ã¾ããã㯠(çå¼ãæãç«ã¤) <=> (ã³ã³ãã¤ã«ãéã) ã¨ãªããããªå¼) import scala.compiletime.ops.int sealed trait List case class Cons[Car, Cdr](car: Car, cdr: Cdr) extends List case class Nil() extends List type Length[L <: List] <: Int = L match { case Nil => 0 case Cons[_, cdr] => int.+[1, Length[cdr]] } trait C summon[Length[Nil] =:= 0] summon[Length[Cons[A, Cons[B, Cons[C, Nil]]]] =:= 3]
ãã¡ããã¡ããããããã. ãããªããããããè¨èªã ã¨æãã°ããã§çæ´»ã§ãã.
ãªãã©ã«åæä½
æ¢ã«ä¸ã®ä¾ã§ä½¿ã£ã¦ãã¾ã£ã¦ãããã©, scala.compiletime.ops.{boolean, int, string}
ãªã©ã§, ãªãã©ã«åã®æä½ãã§ãã. ãªãã©ã«åã®(åã¬ãã«ã§ã®)å¤ã¯ãã®ã¾ã¾ãªãã©ã«ãæ¸ãã°ãããã©, ãããæä½ããçµæããªãã©ã«åã«ããããã«ã¯, åã¬ãã«ã®æä½ãã§ããå¿
è¦ããã.
import scala.compiletime.ops.string summon[string.+["foo", "bar"] =:= "foobar"]
ããããã¾3.1.2-RC1ã§ã¯æåååã«é¢ãã¦ã ãã¶ãªããã«ãªã£ã¦ãã¦, æ£è¦è¡¨ç¾ããããªããããã(ãã ã使ãã¨ãã¯@annotation.experimental
ãå¿
è¦).
ã©ã ãè¨ç®ã®å®è£
åºæ¬çã«ã¯(æ§æ解æå¨ä»¥å¤ã¯)C++çã翻訳ãã¦ããã°ãã. ã©ã¡ããã¨è¨ãã¨Scala 3çãæ¸ããããC++çãèªãæ¹ãã ãã.
è©ä¾¡
ã¾ãã¯é
ã¯ããããæãã«å®ç¾©ããã. case class
ã«ãã¦ãã¾ã£ã¦, å¤ã®æ¹ã§æ¸ãã¦ãåããã®ã表ç¾ã§ããããã«ãã¦ããã¨ãªã«ãã¨ã¹ãããããªã®ã§ãããã¦ãã.
sealed trait Term case class Var[V <: String](v: V) extends Term case class Abs[V <: String, T <: Term](v: V, t: T) extends Term case class App[T1 <: Term, T2 <: Term](t1: T1, t2: T2) extends Term
è©ä¾¡å¨ã®å®è£ ã®ä»æ¹ã¯ããã¤ããããã©, é£ãããã¤ã³ãã¯å¤æ°åããã¶ã£ãã¨ãã®æ±ã. ããæ¹ã¯ä½éãããããã©, C++çã¨åæ§ã«De Bruijn indexã§ãã£ã¦ãã. 以ä¸ã¯C++çãæ¸ããã¨ãã®èª¬æ.
ã©ã ãè¨ç®ã§ã¯æ§æä¸ã¯
λx.λx.x
ã¿ãããªãã®ãæ¸ãã¦, æå¾ã®x
ã¯ãµã¤ã2çªç®ã®x
ãããã¦ãããã¨ã«ãã. æ§æä¸åãå¤æ°ã«ããå ¥ãåã®æ½è±¡ãç¦æ¢ããã¨ãã¦ã, ãã¨ãã°(λxy.x) (λy.y)
ãç°¡ç´ãããã¨Î»y.λy.y
ã«ãªãã®ã§, ãã£ã±ãåãå¤æ°ã§å ¥ãåã®æ½è±¡ããã¦ããå ´åã®ãã¨ãèããªãã¨ãããªã. ãããªããã°, ãã¹ã¦ã®å¤æ°ãéãååã«ããå¿ è¦ããã. ããã«åä»ãªãã¨ã«,λy.(λxy.x y) y
ã®å å´ãç°¡ç´ããã¨Î»y.(λy.y y)
ã¨ãªã£ã¦, æå¾ã®y
ã¯2çªç®ã®y
ãããã¦ãã¦, æå¾ãã2çªç®ã®y
ã¯æåã®y
ãããã¦ããã¯ããªã®ã«, 両æ¹ã¨ã2çªç®ã®y
ãããã¦ããå ´åã¨æ§æä¸ã¯åºå¥ãã¤ããªã.
De Bruijn indexã¯, ããããæç¸é¢ä¿ãååã§ç®¡çããã®ãããã¦, å¤æ°ããè¦ã¦ããã¤å¤å´ã®æ½è±¡ãããã¦ãããã¨ããæ°å¤æ å ±ã使ã. ããã使ãã¨
(λxy.x) (λy.y)
ã¯(λλ.2) (λ.1)
ã®ããã«è¡¨ç¾ã§ãã. ãã ã, ç°¡ç´ããã¨ã(ä»£å ¥ããã¨ã)ã«ã¯æ°å¤ãé©åã«ã·ããããªãã¨ãããªã. ãã¨ãã°Î»y.(λxy.x y) y
ã¯Î».(λλ.2 1) 1
ã¨æ¸ãã¦, ãããç°¡ç´ããã«ã¯2
ã®ã¨ããã«æå¾ã®1
ãä»£å ¥ããã°ããããã©, çµæã¯Î»Î».1 1
ã§ã¯ãªã, 1段éæ·±ãã¨ããã¸ä»£å ¥ããã®ã§ã·ãããã¦Î»Î».2 1
ã«ããªãã¨ãããªã.
De Bruijn indexã§è¡¨ç¾ãããé ã¯ããã¾ã§ç°¡ç´ããã¨ãã®ä¸é表ç¾ã§, æå¾ã«ã¯å ã®å¤æ°åã«æ»ããããã, å®éã¯ååãå®å ¨ã«ã¯æ¶ãã¦ãã¾ããªãæ¹ããã.
ã¤ã¾ã, ãã
object DeBruijn { sealed trait Term case class Var[I <: Int](i: I) extends Term case class Abs[T <: Term](t: T) extends Term case class App[T1 <: Term, T2 <: Term](t1: T1, t2: T2) extends Term }
ã§ã¯ãªã, ãã
object DeBruijn { sealed trait Term case class Var[I <: Int, V <: String](i: I, v: V) extends Term case class Abs[V <: String, T <: Term](v: V, t: T) extends Term case class App[T1 <: Term, T2 <: Term](t1: T1, t2: T2) extends Term }
ãã¦ãããæ¹ããã.
ãã®DeBruijn.Term
ã®1ã¹ãããã®ç°¡ç´ã¯ä»¥ä¸ã®ããã«ãªã. åºæ¬çã«ã¯ç°¡ç´åºã®å ´åã ã代å
¥å¦çããã¦, ãã以å¤ã®å ´åã¯å帰çã«å¦çããã¨ããã ã. ãã¤ãã®æãã§ãã.
type Eval1[T <: DeBruijn.Term] <: (DeBruijn.Term, Boolean) = T match { case DeBruijn.App[DeBruijn.Abs[v, t1], t2] => // beta-redex (Subst[t1, t2, 1], true) case DeBruijn.App[t1, t2] => Eval1[t1] match { case (_, false) => Eval1[t2] match { case (t3, true) => (DeBruijn.App[t1, t3], true) case (t3, false) => (DeBruijn.App[t1, t3], false) } case (t3, true) => (DeBruijn.App[t3, t2], true) } case DeBruijn.Abs[v, t] => Eval1[t] match { case (t2, true) => (DeBruijn.Abs[v, t2], true) case (t2, false) => (DeBruijn.Abs[v, t2], false) } case _ => (T, false) }
summon[Eval.Eval1[DeBruijn.Of[App[Abs["x", Abs["y", Var["x"]]], Abs["y", Var["y"]]]]] =:= (DeBruijn.Abs["y", DeBruijn.Abs["y", DeBruijn.Var[1, "y"]]], true)]
ã¾ãå®éã¯ä»£å ¥å¦ç(ã¨ããã«ä¼´ãã¤ã³ããã¯ã¹ã®ã·ãã)ããã¯ãã, ã¿ããªããããã¨ãããªãã ãã©, 説æã¯çç¥. ãªãã¨ããã, ã©ãããå¦çããã¹ããªã®ãããèãã¦æ³¨ææ·±ãæ¸ãã ã. ç解ãæ·±ããã人ã¯ソースコードãåèã«èªåã§æ¸ãã¦ã¿ãã.
å°å
ãã¹ãæãªã©, æ½è±¡æ§ææ¨ã§æ±ãã¨é¢åãªã®ã§, æåååã§ããããã«ãã¦ããã¨ãã. ãããæååãªãã©ã«åã¨ãã®æä½ãå¯è½ã ããåã¬ãã«ã§ã§ãã. ãã¨ã¯æ¬å¼§ã大éã«ããã¨è¦ã¥ãããªããã, æ¬å¼§ã¯å¿ è¦æå°éã«ã§ããã¨ãã. ã¾ãã¨ã«ããã³ã¼ããè¦ã¦ã¿ãã.
type Show[T <: Term] <: String = T match { case Var[v] => v case Abs[_, _] => string.+["λ", Show.AbsBody[T]] case App[t1, t2] => string.+[Show.AppL[t1], string.+[" ", Show.AppR[t2]]] } object Show { type AbsBody[T <: Term] <: String = T match { case Var[_] => string.+[".", Show[T]] case Abs[v, t] => string.+[v, AbsBody[t]] case App[_, _] => string.+[".", Show[T]] } type AppL[T <: Term] <: String = T match { case Var[_] => Show[T] case Abs[_, _] => string.+["(", string.+[Show[T], ")"]] case App[t1, t2] => Show[T] } type AppR[T <: Term] <: String = T match { case Var[_] => Show[T] case Abs[_, _] => string.+["(", string.+[Show[T], ")"]] case App[_, _] => string.+["(", string.+[Show[T], ")"]] } }
summon[Show[Abs["x", Abs["y", Abs["z", App[App[Var["x"], Var["z"]], App[Var["y"], Var["z"]]]]]]] =:= "λxyz.x z (y z)"]
æ§æè¦ç´ ãã¨ã«è¡¨ç¤ºé¢æ°ãåã, ããããåè¦ç´ ã®å½¢ã§å ´ååããããã¨ã§å¿ è¦ãªãã¿ã¼ã³ã ãæ¬å¼§ãã¤ããããã«ã§ãã. ãªããããã¯ããããããã¨ãã£ããæ¸ããã¨ç¥ã£ã¦ããã©ããã®åé¡.
æ§æ解æ
åã¬ãã«ã®æ§æ解æå¨ã¯åãã¦æ¸ãã®ã§, ãããªãã«è¦å´ãã. åã¬ãã«ã ããè¦å´ããã¨ãããã, ç´ç²é¢æ°åã®æ¥µå°è¨èªã§, ã³ã³ãã¯ãã«ãã£ãã, ã§ããªãã¹ãææ©ãããã«ã¯ã©ãããããããã¨ããã¨ãã.
æ¬å¼§ãæ¸ãã¦ãçç¥ãã¦ããã¾ã解æã§ãã¦ã»ããã, ãªããããã«ãé¢åãããããªæãããã. ãã¼ãµã³ã³ããã¼ã¿ã¨ãã§æ¸ããã. å¢ãä½ã£ã¦åã¬ãã«ã®ãã¼ãµã³ã³ããã¼ã¿ãå®è£ ããããã¨æã£ããã©, ããã¾ã§åã¬ãã«ã®è¨èªã¨ãã¦è¦ãã¨ãã®æ½è±¡åè½åã¯ããã¾ã§é«ããªãããã§, ããªã大å¤ããã§è«¦ãã. ããã諦ãããå²ã¨ãããªãæ¸ãã.
èãæ¹ã¨ãã¦ã¯, ãã¼ãµã³ã³ããã¼ã¿ã§æ¸ããããªã¤ããã§ããã, ã³ã³ããã¼ã¿ã®åæã¯ãããã«æã§åãè¾¼ãã§ãã. ã¾ãã¯ãã¼ãµã³ã³ããã¼ã¿ã§æ¸ããããããªå½¢(ãªããååã¨ãçè«ã¨ããããããªæ°ããããã©, ããããã®ã§åã§)ã®BNFãæ¸ãã. ãããã¬ãã«ã¨ãªãè¦ç´ ã«ååãã¤ãã¦ãã. ã±ã±ã£ã¨æ¸ãã¦æ¬å¼§ãçç¥ã§ããªãé¨åã¯ã©ãããèãã¦(å°åã®ã¨ãã«èãã¦ããã®ã¨ã»ã¼åããã¨)調æ´ãã¦ããã¨ãããªå ·åã®ãã®ãã§ãã.
// e := λf [ParseExp] // a // f := x.e [ParseAbs] // xf // a := p [ParseApp] // a p // p := x [ParsePrimary] // (e)
ãã¼ãµã³ã³ããã¼ã¿ã£ã½ããªã«ããä½ããã¨ãã¦ãããã, å ¥åãåãåã£ã¦, 解æçµæã¨æ®ãã®å ¥åãè¿ãé¢æ°ã¨ãã¦å®ç¾©ããã¨ããã¯ã. å ¥åã¯æ¬æ¥ã¯åå¥è§£æçµæã«ãªããã©, æ¡å¤æååãã®ã¾ã¾ã«ãã¦ãã¾ã£ã¦ã³ã³ããã¼ã¿ã®ä¸ã§æ£è¦è¡¨ç¾ãããã¨ããã¦ãã¾ã£ãæ¹ããæ軽ã«å®è£ ã§ããã¿ãããªè©±ãã©ããã§è¦ãè¨æ¶ãããã®ã§ä»åã¯ãããã¦ã¿ã. ããããã¤ã¡ã¼ã¸.
type Parse[S <: String] <: (Term, String)
ããã解æã¨ã©ã¼ãæ±ããããã, è¿ãå¤ã¯ã¡ããã¨åãå®ç¾©ããæ¹ãè¦éãããã. ããã¨ãããªã.
sealed trait ParseResult case class ParsedTerm[T <: Term, R <: String](term: T, rest: R) extends ParseResult case class ParseError[R <: String](reason: R) extends ParseResult
type Parse[S <: String] <: ParseResult
ã¨ãããã¨ã§ããã«æ²¿ã£ã¦, BNFã§æ¸ããåã«ã¼ã«ãå®è£
ãã¦ããã°ãã. ã¾ãã¯ä¸çªç°¡åãªParsePrimary
ãã.
type ParsePrimary[Src <: String] <: ParseResult = Matches[SafeSubstring[Src, 0, 1], "[a-z]"] match { case true => ParsedTerm[Var[Substring[Src, 0, 1]], Substring[Src, 1, Length[Src]]] case _ => SafeSubstring[Src, 0, 1] match { case "(" => ParseExp[Substring[Src, 1, Length[Src]]] match { case ParsedTerm[t, rest] => Substring[rest, 0, 1] match { case ")" => ParsedTerm[t, Substring[rest, 1, Length[rest]]] case _ => ParseError["unclosed parenthesis"] } case ParseError[s] => ParseError[s] } case _ => ParseError["variable or parenthesis expected"] } }
å¤æ°ã®ã¿ã®å ´å(x
ã®æ¹ã®ãã¿ã¼ã³)ã¨æ¬å¼§ãããã¨ãã«å ´ååããã¦ãã. å ´ååãããã1æåèªãã ãããé¨åã, ãã¼ãµã³ã³ããã¼ã¿ã ã£ããå¥ã
ã®ã³ã³ããã¼ã¿ã«ãªã£ã¦ãã¦åæãã¦è¡¨ç¾ããã¨ããã ãã©, ãã®ã¾ã¾åãè¾¼ãã§æ¸ãã¦ããã¤ã¡ã¼ã¸. æ¬å¼§ã®æ¹ã®ä¸èº«ã¯ParseExp
ãç¸äºå帰çã«å¼ã³åºãã¦èªã.
次ã¯ParseApp
ãè¦ã¦ã¿ãã.
type ParseApp[Src <: String] <: ParseResult = ParsePrimary[Src] match { case ParsedTerm[t, rest] => ParseApp1[t, rest] case ParseError[s] => ParseError[s] } type ParseApp1[Prev <: Term, Src <: String] <: ParseResult = SafeSubstring[Src, 0, 1] match { case " " => ParsePrimary[Substring[Src, 1, Length[Src]]] match { case ParsedTerm[t, rest] => ParseApp1[App[Prev, t], rest] case ParseError[s] => ParseError[s] } case _ => ParsedTerm[Prev, Src] }
ã«ã¼ã«ãããçºããã¨ã¹ãã¼ã¹åºåãã§ParsePrimary
ãã§ããã ãããã°ããã¨ããã. App
ã¯å·¦çµåãªã®ã§, 1ã¤åã«è¦ããã®ãå¼æ°ã§åãåãParseApp1
ãç¨æãã¦, 次ãèªã度ã«App
ã®ã¤ã³ã¹ã¿ã³ã¹ãä½ã£ã¦ããããã«ãã. åºåãã®ã¹ãã¼ã¹ãç¾ããªããªã£ãããã¹ã¦èªã¿åã£ãã®ã§ããã¾ã§ã«ä½ã£ãé
ããã®ã¾ã¾è¿ãã°ãã.
æå¾ã«ParseAbs
ãè¦ã¦ã¿ãã.
type ParseAbs[Args <: HList, Src <: String] <: ParseResult = Matches[Src, "[a-z][.].*"] match { case true => ParseExp[Substring[Src, 2, Length[Src]]] match { case ParsedTerm[t, rest] => ParsedTerm[MakeAbs[Substring[Src, 0, 1] :+: Args, t], rest] case ParseError[s] => ParseError[s] } case _ => Matches[SafeSubstring[Src, 0, 1], "[a-z]"] match { case true => ParseAbs[Substring[Src, 0, 1] :+: Args, Substring[Src, 1, Length[Src]]] case _ => SafeSubstring[Src, 0, 1] match { case "" => ParseError["unexpected EOF"] case _ => ParseError[string.+["unexpected token: ", Substring[Src, 0, 1]]] } } }
ã¾ãx.e
ã®å½¢ã«ãªã£ã¦ããã調ã¹ã(å
é ãx.
ã«ãªã£ã¦ãããè¦ã). ãªã£ã¦ããã°æ¬¡ã¯e
ãªã®ã§ParseExp
ãå¼ã¶.
ãã1ã¤ã®xf
ã®å½¢ã®å ´åã¯, ã¾ãx
ã®é¨åãèªãã§, 次ã¯f
ãªã®ã§ParseAbs
ãå帰çã«å¼ã³åºã. èªãã x
ã®ã¨ãããArgs
ã«ç©ãã§ãã£ã¦ãã®ããã¤ã³ãã§, ããã¯ãã¨ã§1ã¤ç®ã®ãã¿ã¼ã³ã§MakeAbs
ã«æ¸¡ãã¦ä¸æ°ã«Abs
ã®æ½è±¡æ§ææ¨ãçµã¿ç«ã¦ã. Args
ã«ã¯éé ã«ç©ã¾ãããã¨ã«ãªããã©, å
å´ããä½ããã(å³çµåçã«ãªã£ã¦ãã)ã®ã§ãããé½åããã.
ãªããä¸è¬è«ã¨ãã¦, æ½è±¡æ§ææ¨ã®çµã¿ç«ã¦ã¯, å·¦çµåã®å ´åã¯1ã¤åã®ãã¤ã次ã¸æ¸¡ãã¦é½åº¦ãã, å³çµåã®å ´åã¯éé ã«ãªã¹ãã«æºãã¦ãã£ã¦ã¾ã¨ãã¦ãã, ã¨ããæãã§ã¤ã±ããã ããã??
å®å ¨ãªã½ã¼ã¹ã³ã¼ãã¯こちら.
ããã¾ã§ã§ããã¨, æååããã¼ã¹ãã¦å®è¡çµæãæååã§è¿ããã¨ãã§ããããã«ãªã.
type ReadEvalPrint[Src <: String] <: String = Src match { // ç¡æå³ãª match ãæã¾ãªãã¨ãªããå¤ã«ã¨ã©ã¼ã«ãªã case _ => Show[Eval[Parse[Src]]] }
summon[ReadEvalPrint["(λxyz.x z (y z)) (λxy.x) (λxy.x)"] =:= "λz.z"]
åæ¨è« (åæ¤æ»)
åæ¤æ»å¨ã¯è©ä¾¡å¨ã¨ã¯ç¬ç«ããæ¦å¿µã§, æ§æ解æããçµæã«å¯¾ãã¦åãè¿ããã®ã¨ãã¦å®è£ ã§ãã.
summon[Show[Type.Infer[lambda.Parse["(λxyz.x z (y z)) (λxy.x) (λxy.x)"]]] =:= "a -> a"]
ã©ããã£ã¦å®è£ ããã. ããã¯ãã, ã¡ãã£ã¨é次説æããã®ã¯å¤§å¤ããã(åæã¨ãªã話ã ãã§ãé·å¤§ãªè¨äºã«ãªã)ãã, ãã®è¾ºã®ãèªãã§ãã ãã(ã¨ãã«4.4ã¨4.5ã®è¾ºã). ã ããããã£ã¦ããã¨ã¯åã.
ãã®è³æã®è¬ç¾©(ãäºååµæ·³å çããã£ã¦ããé )ã®TAãæãã£ã¦ãããã, åæ¨è«å¨ã®å®è£ ã¯100ä¸åããããã£ã¦ãã¦ãããã©ãããããã£ã¦ãããã ãã©, ããã§ããããã°ã¯ã¡ãã£ã¨å¤§å¤ã ã£ã.
ãã¡ãã, ã©ããã(åã¬ãã«è¨èªä¸ã®)å¤ã«ãªã£ã¦ããã確èªãããã£ãã,
def test: SomeType = ""
ã¨ãããã°(è¦ããåãæåååã ã£ããé©å½ã«= 1
ã¨ã§ããã)ã³ã³ãã¤ã«ã¨ã©ã¼ã®ã¡ãã»ã¼ã¸ã§SomeType
ãã©ããªã£ã¦ããè¦ãããã, printfãããã°çãªãã¨ãã§ããªãã¯ãªã. ãã©ã¾ãã ãã.
ã¡ãªã¿ã«ä»åã¯, App
ã®å¼ã®åãè¿ãã¨ããã§, ãã¬ãã·ã¥ã«å²ãå½ã¦ãå¤æ°ãè¿ãã®ãæ£ããã¨ããã, ééã£ã¦é¢æ°é©ç¨ã®å·¦è¾ºã®åãè¿ãã¦ãã¾ã£ã¦ãã¦, ããã«æ°ã¥ãã¾ã§ã«1æéãããããã£ãããã.
ã¨ã¯ãã今回の実装ã¯, OCamlã¨ãã§æ¸ãããã®ã¨æ¯è¼ãã¦ã, å²ã¨ãã£ããæ¸ãã¦ããæ°ããã. è¨èªæ©è½ãªãã¦ãã¿ã¼ã³ãããã¨å帰å¼ã³åºãã ãããã°ããã§ããã£ããã, ã¨ããæ°æã¡ã«ãªã£ã¦ãã.
ãããã«
ã¨ããããã§, ãã§ããScala 3ã®åã·ã¹ãã ããã¥ã¼ãªã³ã°å®å ¨ã§ãããã¨ãããã£ã. ã ããããªãã§ãæ¸ããã®ã§, ã¿ããªãã®ããã°ã¦ã§ã¼ã´ã«ä¹ã£ã¦, æãæãã®ãåã¬ãã«ââããã³ã³ãã¤ã«æââããå®ç¾ãã¦ã¿ãã¨ããããããªãã ããã. ãã¿ããªããã£ã¦ãã人ã«ã¯JSONãã¼ãµ, jqå¦çç³», é¢æ£ãã¼ãªã¨å¤æ, ã¬ã¤ãã¬ã¼ã·ã³ã°ãããããããããã¦ããã¾ã. ã©ããããç°¡åã«ã§ãããã¯ç¥ããªã.