Created
February 7, 2012 09:35
-
-
Save einblicker/1758706 to your computer and use it in GitHub Desktop.
Javaで型安全なprintf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Func<A, B> { | |
B apply(final A arg); | |
} | |
abstract class Dir<A, B> { | |
public Dir() {} | |
abstract public Func<Func<String, A>, Func<String, B>> format(); | |
} | |
class DLit<A> extends Dir<A, A> { | |
private String s; | |
public DLit(String s) { | |
this.s = s; | |
} | |
public Func<Func<String, A>, Func<String, A>> format() { | |
return new Func<Func<String, A>, Func<String, A>>() { | |
public Func<String, A> apply(final Func<String, A> cont) { | |
return new Func<String, A>() { | |
public A apply(final String out) { | |
return cont.apply(out + s); | |
} | |
}; | |
} | |
}; | |
} | |
} | |
class DInt<A> extends Dir<A, Func<Integer, A>> { | |
public DInt() {} | |
public Func<Func<String, A>, Func<String, Func<Integer, A>>> format() { | |
return new Func<Func<String, A>, Func<String, Func<Integer, A>>>() { | |
public Func<String, Func<Integer, A>> apply(final Func<String, A> cont) { | |
return new Func<String, Func<Integer, A>>() { | |
public Func<Integer, A> apply(final String out) { | |
return new Func<Integer, A>() { | |
public A apply(Integer i) { | |
return cont.apply(out + i.toString()); | |
} | |
}; | |
} | |
}; | |
} | |
}; | |
} | |
} | |
class DStr<A> extends Dir<A, Func<String, A>> { | |
public DStr() {} | |
public Func<Func<String, A>, Func<String, Func<String, A>>> format() { | |
return new Func<Func<String, A>, Func<String, Func<String, A>>>() { | |
public Func<String, Func<String, A>> apply(final Func<String, A> cont) { | |
return new Func<String, Func<String, A>>() { | |
public Func<String, A> apply(final String out) { | |
return new Func<String, A>() { | |
public A apply(String s) { | |
return cont.apply(out + s); | |
} | |
}; | |
} | |
}; | |
} | |
}; | |
} | |
} | |
class DCon<A, B, C, D> extends Dir<C, B> { | |
private Dir<A, B> d1; | |
private Dir<C, A> d2; | |
public DCon(Dir<A, B> d1, Dir<C, A> d2) { | |
this.d1 = d1; | |
this.d2 = d2; | |
} | |
public Func<Func<String, C>, Func<String, B>> format() { | |
return new Func<Func<String, C>, Func<String, B>>() { | |
public Func<String, B> apply(final Func<String, C> cont) { | |
return new Func<String, B>() { | |
public B apply(final String out) { | |
return d1.format().apply(d2.format().apply(cont)).apply(out); | |
} | |
}; | |
} | |
}; | |
} | |
} | |
class SafeFormatter { | |
public static <A> A format(Dir<String, A> d) { | |
return d.format().apply(new Func<String, String>() { | |
public String apply(final String a) { | |
return a; | |
} | |
}).apply(""); | |
} | |
public static <A> Dir<A, A> newDLit(String s) { | |
return new DLit<A>(s); | |
} | |
public static <A> Dir<A, Func<Integer, A>> newDInt() { | |
return new DInt<A>(); | |
} | |
public static <A> Dir<A, Func<String, A>> newDStr() { | |
return new DStr<A>(); | |
} | |
public static <A, B, C, D> Dir<C, B> newDCon(Dir<A, B> d1, Dir<C, A> d2) { | |
return new DCon<A, B, C, D>(d1, d2); | |
} | |
public static void main(String[] args) { | |
//型安全なSystem.out.printf("hello, %s!", "world")を表現している。 | |
Dir<Func<String, String>, Func<String, String>> d1 = newDLit("hello, "); | |
Dir<String, Func<String, String>> d2 = newDStr(); | |
Dir<String, String> d3 = newDLit("!"); | |
System.out.println(format(newDCon(newDCon(d1, d2), d3)).apply("world")); | |
//System.out.println(format(newDCon(newDCon(d1, d2), d3)).apply(123)); //String以外の型はコンパイルエラー | |
//型安全なSystem.out.printf("a: %d b: %d c: %d", 1, 2, 3)を表現している。 | |
Dir<Func<Integer, Func<Integer, Func<Integer, String>>>, | |
Func<Integer, Func<Integer, Func<Integer, String>>>> d4 = newDLit("a: "); | |
Dir<Func<Integer, Func<Integer, String>>, | |
Func<Integer, Func<Integer, Func<Integer, String>>>> d5 = newDInt(); | |
Dir<Func<Integer, Func<Integer, String>>, | |
Func<Integer, Func<Integer, String>>> d6 = newDLit(" b: "); | |
Dir<Func<Integer, String>, | |
Func<Integer, Func<Integer, String>>> d7 = newDInt(); | |
Dir<Func<Integer, String>, Func<Integer, String>> d8 = newDLit(" c: "); | |
Dir<String, Func<Integer, String>> d9 = newDInt(); | |
System.out.println( | |
format(newDCon(newDCon(newDCon(newDCon(newDCon(d4, d5), d6), d7), d8), d9)) | |
.apply(1).apply(2).apply(3) | |
); | |
//System.out.println( | |
// format(newDCon(newDCon(newDCon(newDCon(newDCon(d4, d5), d6), d7), d8), d9)) | |
// .apply('a').apply('b').apply('c') | |
//); //Integer以外の型はコンパイルエラー | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment