tweag/inline-java

Support type parameters

facundominguez opened this issue · 0 comments

Is your feature request related to a problem? Please describe.

It is difficult to use quasiquotations that are type safe and can be reused with different types.

f :: (IsReferenceType a, Coercible a) => a -> IO a
f obj = [java| $obj |]

The above code is rejected because at compile time, inline-java doesn't know which Java type to give to $obj.
We can do casts instead:

f :: (IsReferenceType a, Coercible a) => a -> IO a
f (coerce -> JObject obj) = unsafeUncoerce . JObject <$> [java| $obj |]

which can fail at runtime if the user gets the types wrong.

Describe the solution you'd like

Ideally, we would have in Java code like

public <A> A f (A $obj) { return $obj; }

and our initial definition would be accepted

f :: (IsReferenceType a, Coercible a) => a -> IO a
f obj = [java| $obj |]

The code generated by inline-java would be responsible for making the appropriate casts.

There is some room to decide where type variables are allowed in a type. Here's an example where the type variable appears nested within a type.

f :: (IsReferenceType a, Coercible a) => a -> IO (J ('Iface "java.util.List" <> '[ Ty a ]))
f _ = [java| new ArrayList<A>() |]

And we also would have to consider if/how to deal with bounded type parameters.