OCaml, Concurrent Clean, Java: 型からプログラムを生成する
http://itpro.nikkeibp.co.jp/article/COLUMN/20071005/283903/
む。
Genericsの定義の仕方に似てるなー。
-
-
- -
-
とりあえず、脊髄反射でCleanとJavaに翻訳
Java版はやや無理があるけど、一応ちゃんと動きます。出力形式をOCaml形式にしてますけど、Java式に出力することもできるはず。
Clean版
module Main import Misc, List, String, StringCast :: T a = {val2str :: [String] a -> String ,str2val :: [String] String -> a } dup ls = (skip ls, skip (tail ls)) where skip [a,b:c] = [a: skip c] getSym = map (\i = "x" + toString i) [1..] z =: {val2str = \sym v = v ,str2val = \sym s = s } (^->) infixr 9 :: (T a) (T b) -> T (a -> b) (^->) t1 t2 = {val2str = val2str, str2val = str2val} where val2str [x:sym] f = "(\\" + x + " = " + body + ")" where (sym1,sym2) = dup sym body = t2.val2str sym2 $ f $ t1.str2val sym1 x str2val sym s x = t2.str2val sym2 $ s + " " + (t1.val2str sym1 x) where (sym1,sym2) = dup sym (*^) infixl 9 :: (T a) (T b) -> T (a,b) (*^) t1 t2 = {val2str = val2str, str2val = str2val} where val2str sym (v1,v2) = "(" + s1 + "," + s2 + ")" where (sym1,sym2) = dup sym s1 = t1.val2str sym1 v1 s2 = t2.val2str sym2 v2 str2val sym s = (v1,v2) where (sym1,sym2) = dup sym v1 = t1.str2val sym1 ("fst " + s) v2 = t2.str2val sym2 ("snd " + s) Start = t.val2str getSym f where t = z ^-> z ^-> z f a b = a
Java版
public class Main { static int ct = 0; static String genSym () { return "x" + (++ct);} static interface Fun<Y,X> { X $ (Y y);} static interface T<A> { String val2str (A a); A str2val (String s); } static T<String> z = new T<String> () { public String val2str (String a) { return a;} public String str2val (String a) { return a;} }; static <A,B> T<Fun<A,B>> fun (final T<A> t1, final T<B> t2) { return new T<Fun<A,B>> () { public String val2str (Fun<A,B> f) { String x = genSym (); String body = t2.val2str( f.$ (t1.str2val (x))); return "(fun " + x + " -> " + body + ")"; } public Fun<A,B> str2val (final String s) { return new Fun<A,B> (){ public B $ (A x) { return t2.str2val (s + " " + t1.val2str(x));} }; } }; } public static void main (String[] args) { Fun<String,Fun<String,String>> f = f(); String s = fun(z,fun(z,z)).val2str(f); System.out.println(s); } static <A,B> Fun<A,Fun<B,A>> f () { return new Fun<A,Fun<B,A>> () { public Fun<B,A> $ (final A a) { return new Fun<B,A> () { public A $ (B b) { return a;} }; } }; } }