多相型バリアント
SML#の多相型バリアントの表現のところを見てて、よくわからないので
JavaScriptに移植して理解しようとしてみた。
http://www.pllab.riec.tohoku.ac.jp/smlsharp/ja/?Resorces%2FProgrammingExamples%2FVariants
このへんや、
http://www.pllab.riec.tohoku.ac.jp/smlsharp/ja/?VariantSource
この辺見て、JavaScriptに移植する。+JavaScriptでもdのmixinっぽくってのをやってみた。
SMLはOCamlとかよりも、結構Cに近いというか、JavaScriptに近い感じがします。
Ocamlがやっぱり、括弧やら、セミコロンやらをうまく使ってるよなぁとも思うのでした。
function variant(s) { var ss = s.split("|"); for(var i = 0; i < ss.length; i++) { var sss = ss[i]; var m = sss.match(/\s*([^\s\(]+)\s*\(([^\)]*)\)/); var m2 = m[2].split(","); for (var j = 0; j < m2.length; j++) m2[j] += ":" + m2[j]; eval(m[1] + "=function("+m[2]+"){return function(M){return M."+m[1]+"({"+m2.join(",")+"});};};"); } } function fn(str) { return function(_) {with(_){ return eval("_="+str); }}; } Object.prototype.toString = function() { var str = ""; for(var i in this) { str += i + ":"+ this[i]+","; } if (str != "") str = str.substring(0,str.length-1); return "{" + str + "}"; } variant("CPoint(x,y)|PPoint(r,theta)"); var r = { CPoint: fn("Math.sqrt(x * x + y * y)"), PPoint: fn("r") }; var theta = { CPoint: fn("(Math.atan(x / y)/Math.PI)*180.0"), PPoint: fn("theta") }; var x = { CPoint: fn("x"), PPoint: fn("Math.cos(theta/180.0*Math.PI)*r") }; var y = { CPoint: fn("y"), PPoint: fn("Math.sin(theta/180.0*Math.PI)*r") }; var toCPoint = { CPoint: fn("_"), PPoint: fn("CPoint(PPoint(r,theta)(x),PPoint(r,theta)(y))(toCPoint)") }; var toPPoint = { CPoint: fn("PPoint(CPoint(x,y)(r), CPoint(x,y)(theta))(toPPoint)"), PPoint: fn("_") }; var p1 = CPoint(10.0, 10.0); var p2 = PPoint(14.1421356, 45.0); alert(p1(r)); alert(p2(r)); alert(p1(theta)); alert(p2(theta)); alert(p1(x)); alert(p2(x)); alert(p1(y)); alert(p2(y)); alert(p1(toCPoint)); alert(p2(toCPoint)); alert(p1(toPPoint)); alert(p2(toPPoint)); /* function iterator(L,f) { map (function(x){return x(f);}, L); } var myPointList = [P1,P2]; function myPointLstIter(x) { iterator(myPointList, x); } myPointLstIter(distance); myPointLstIter(angle); */