暗黙的型変換
ここの所は、夏の疲れがまだ取れないって感じなのですが、ちょっとだけ進めました。
この間のソースはコンパイルすら通らないという、どんだけやる気なかったのかと思ったりします。
思ったりするけど、まぁ、何も書かないよりは良い。ちょっとでも進み続ける。コレ大事だと思うのでした。
とりあえず、最後のコードが通ってないのと例外投げまくりなのが問題なのでなんとかしないとなっと。
package type5; object Main { trait TType case class TFloat() extends TType case class TInt() extends TType case class TNone() extends TType case class TStr() extends TType case class TFun(prms:List[TType],rc:TType) extends TType sealed abstract case class E(t:TType) case class EId(s:String) extends E(TStr()) case class ECast(override val t:TType, a:E) extends E(t) case class EInt(override val t:TType, a:scala.Int) extends E(t) case class EFloat(override val t:TType, a:Double) extends E(t) case class ECall(override val t:TType, f:E, a:List[E]) extends E(t) def main(argv:Array[String]) { println("*"+f(ECall(TNone(),EId("add"),List(EFloat(TFloat(),1),EInt(TInt(),2))))) println("*"+f(ECall(TNone(),EId("add"),List(EInt(TInt(),1),EInt(TInt(),2))))) println("*"+f(ECall(TNone(),EId("add"), List(ECall(TNone(),EId("add"),List(EFloat(TFloat(),1),EInt(TInt(),1))),EInt(TInt(),2))))) } def f(e:E):E = e match { case ECast(t,a) => ECast(t, f(a)) case EInt(t,i) => EInt(TInt(), i) case EFloat(t,i) => EFloat(TFloat(), i) case ECall(t,id,xs) => println("xs "+xs) val fns = f(id) match { case EId(a) => functions(a) case _ => throw new Exception("not found method "+id) } def tpc(ts:List[TType],es:List[E]):Boolean = { (ts,es) match { case (List(),List()) => true case (t::ts,e::es) => if(t!=e.t) false else tpc(ts,es) case _ => false } } //println("fns "+fns) for(i <- fns) { i match { case TFun(l,r) => //println("tfun "+l+" "+r) if (tpc(l, xs)) return ECall(i,id, xs.map(f)) case _ => throw new Exception("not found method") } } def tpc2(ts:List[TType],es:List[E]):List[E] = { //println("tpc2 "+(ts,es)) (ts,es) match { case (List(),List()) => List() case (t::ts,e::es) => println("koko "+t+" "+e) if(t==e.t) { e::tpc2(ts,es) } else if(implicitConversions.contains(t->e.t)){ println("contains implicits "+t + " "+e) implicitConversions(t->e.t)(e)::tpc2(ts,es) } else { throw new Exception("error") } case _ => throw new Exception("error") } } // そのままの型がないので暗黙の型変換を探す for(i <- fns) { try { i match { case TFun(l,r) => return ECall(i,id, tpc2(l, xs).map(f)) case _ => } } catch { case e:Exception => } } throw new Exception("not found method "+e) case EId(a) => EId(a) } def typs(e:E):TType = e.t // 関数定義表 var functions = Map[String,List[TType]]( "add"->List( TFun(List(TInt(),TInt()),TInt()), TFun(List(TStr(),TStr()),TStr()), TFun(List(TFloat(),TFloat()),TFloat()) ) ) // 暗黙の型変換の表 var implicitConversions = Map[(TType,TType),(E)=>E] ( (TInt(),TStr()) -> ((a:E)=>ECast(TStr(),a)), (TFloat(),TStr()) -> ((a:E)=>ECast(TStr(),a)), (TFloat(),TInt()) -> ((a:E)=>ECast(TFloat(),a)) ) }