Asking this question to clarify my understanding of type classes and higher kinded types, I'm not looking for workarounds in Java.
In Haskell, I could write something like
class Negatable t where negate :: t -> t normalize :: (Negatable t) => t -> t normalize x = negate (negate x)
Then assuming Bool
has an instance of Negatable
,
v :: Bool v = normalize True
And everything works fine.
In Java, it does not seem possible to declare a proper Negatable
interface. We could write:
interface Negatable { Negatable negate(); } Negatable normalize(Negatable a) { a.negate().negate(); }
But then, unlike in Haskell, the following would not compile without a cast (assume MyBoolean
implements Negatable
):
MyBoolean val = normalize(new MyBoolean()); // does not compile; val is a Negatable, not a MyBoolean
Is there a way to refer to the implementing type in a Java interface, or is this a fundamental limitation of the Java type system? If it is a limitation, is it related to higher-kinded type support? I think not: it looks like this is another sort of limitation. If so, does it have a name?
Thanks, and please let me know if the question is unclear!
An interface is defined with the keyword interface and it can include properties and method declarations using a function or an arrow function.
From Java 8 you can define static methods in interfaces in addition to default methods. A static method is a method that is associated with the class in which it is defined rather than with any object.
Yes, you can define a class inside an interface. In general, if the methods of the interface use this class and if we are not using it anywhere else we will declare a class within an interface.
An interface is declared by using the interface keyword. It provides total abstraction; means all the methods in an interface are declared with the empty body, and all the fields are public, static and final by default. A class that implements an interface must implement all the methods declared in the interface.
Actually, yes. Not directly, but you can do it. Simply include a generic parameter and then derive from the generic type.
public interface Negatable<T> { T negate(); } public static <T extends Negatable<T>> T normalize(T a) { return a.negate().negate(); }
You would implement this interface like so
public static class MyBoolean implements Negatable<MyBoolean> { public boolean a; public MyBoolean(boolean a) { this.a = a; } @Override public MyBoolean negate() { return new MyBoolean(!this.a); } }
In fact, the Java standard library uses this exact trick to implement Comparable
.
public interface Comparable<T> { int compareTo(T o); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With