import java.lang.*;
import java.io.*;
class JavaTypeClasses {
// class Num t where ...
public interface Num<T> {
T add(T a, T b);
T mul(T a, T b);
}
// instance Num Int where...
public static final class NumInt implements Num<Integer>{
static final NumInt typeClass = new NumInt();
return a + b;
}
return a * b;
}
}
// instance Num Double where...
public static final class NumDouble implements Num<Double> {
static final NumDouble typeClass = new NumDouble();
return a + b;
}
return a * b;
}
}
// Num a => a -> a
public static <T> T times2(Num<T> num, T x) {
return num.add(x, x);
}
// Num a => a -> a
public static <T> T square(Num<T> num, T x) {
return num.mul(x, x);
}
{
Double doubleSix
= times2
(NumDouble.
typeClass,
Double.
valueOf(3)); Double doubleNine
= square
(NumDouble.
typeClass,
Double.
valueOf(3)); System.
out.
println(doubleSix
); System.
out.
println(doubleNine
); }
}
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgamF2YS5pby4qOwoKY2xhc3MgSmF2YVR5cGVDbGFzc2VzIHsKCS8vIGNsYXNzIE51bSB0IHdoZXJlIC4uLgoJcHVibGljIGludGVyZmFjZSBOdW08VD4gewoJCVQgYWRkKFQgYSwgVCBiKTsKCQlUIG11bChUIGEsIFQgYik7Cgl9CgkKCS8vIGluc3RhbmNlIE51bSBJbnQgd2hlcmUuLi4KCXB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTnVtSW50IGltcGxlbWVudHMgTnVtPEludGVnZXI+ewoJCXN0YXRpYyBmaW5hbCBOdW1JbnQgdHlwZUNsYXNzID0gbmV3IE51bUludCgpOwoJCQoJCXB1YmxpYyBJbnRlZ2VyIGFkZChJbnRlZ2VyIGEsIEludGVnZXIgYikgewoJCQlyZXR1cm4gYSArIGI7CgkJfQoJCQoJCXB1YmxpYyBJbnRlZ2VyIG11bChJbnRlZ2VyIGEsIEludGVnZXIgYikgewoJCQlyZXR1cm4gYSAqIGI7CgkJfQoJfQoJCgkvLyBpbnN0YW5jZSBOdW0gRG91YmxlIHdoZXJlLi4uCglwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE51bURvdWJsZSBpbXBsZW1lbnRzIE51bTxEb3VibGU+IHsKCQlzdGF0aWMgZmluYWwgTnVtRG91YmxlIHR5cGVDbGFzcyA9IG5ldyBOdW1Eb3VibGUoKTsKCQkKCQlwdWJsaWMgRG91YmxlIGFkZChEb3VibGUgYSwgRG91YmxlIGIpIHsKCQkJcmV0dXJuIGEgKyBiOwoJCX0KCQkKCQlwdWJsaWMgRG91YmxlIG11bChEb3VibGUgYSwgRG91YmxlIGIpIHsKCQkJcmV0dXJuIGEgKiBiOwoJCX0KCX0KCQoJLy8gTnVtIGEgPT4gYSAtPiBhCglwdWJsaWMgc3RhdGljIDxUPiBUIHRpbWVzMihOdW08VD4gbnVtLCBUIHgpIHsKCQlyZXR1cm4gbnVtLmFkZCh4LCB4KTsKCX0KCQoJLy8gTnVtIGEgPT4gYSAtPiBhCglwdWJsaWMgc3RhdGljIDxUPiBUIHNxdWFyZShOdW08VD4gbnVtLCBUIHgpIHsKCQlyZXR1cm4gbnVtLm11bCh4LCB4KTsKCX0KCQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CgkJSW50ZWdlciBpbnRTaXggPSB0aW1lczIoTnVtSW50LnR5cGVDbGFzcywgSW50ZWdlci52YWx1ZU9mKDMpKTsKCQlJbnRlZ2VyIGludE5pbmUgPSBzcXVhcmUoTnVtSW50LnR5cGVDbGFzcywgSW50ZWdlci52YWx1ZU9mKDMpKTsKCQlEb3VibGUgZG91YmxlU2l4ID0gdGltZXMyKE51bURvdWJsZS50eXBlQ2xhc3MsIERvdWJsZS52YWx1ZU9mKDMpKTsKCQlEb3VibGUgZG91YmxlTmluZSA9IHNxdWFyZShOdW1Eb3VibGUudHlwZUNsYXNzLCBEb3VibGUudmFsdWVPZigzKSk7CgkJU3lzdGVtLm91dC5wcmludGxuKGludFNpeCk7CgkJU3lzdGVtLm91dC5wcmludGxuKGludE5pbmUpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihkb3VibGVTaXgpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihkb3VibGVOaW5lKTsKCX0KfQ==