More type mystery

Paul Govereau paul.govereau at oracle.com
Tue Feb 11 07:52:29 PST 2014


Hi Marc,

Java's type inference isn't always able to fill in missing types. Sometimes the 
programmer must supply some types manually as hints to type inference. 
Unfortunately, your program is one of these cases. Technically, this error 
stems from the fact that the method invocation of apply is not a "poly 
expression" as described in section 15.12 of the Java Language Specification 
version 1.8. This means type inference will not propagate type constraints 
through this expression, and therefore is unable to figure out how to 
instantiate the parameter T of IS_ZERO.

As you discovered, you can supply type information by using a variable for part 
of your expression with the correct type. Another way is to manually supply the 
type parameter for the generic method using this syntax:

   Test.<Boolean>IS_ZERO()

Your last example provides the necessary type information by adding an argument 
that requires (T=Boolean) for the generic method to be called.

My understanding is that this particular constraint may be able to be relaxed. 
However, more work is needed to verify this before any changes can be made to 
Java's type inference.

Paul

On 02/08/2014 09:35 AM, Marc Petit-Huguenin wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> With these static methods:
>
> static<T> UnaryOperator<UnaryOperator<T>> ZERO() { return p -> x -> x; }
> static<T> UnaryOperator<UnaryOperator<T>> ONE() { return p -> x -> p.apply(x); }
> static<T> Function<T,UnaryOperator<T>> TRUE() { return x -> y -> x; }
> static<T> Function<T,UnaryOperator<T>> FALSE() { return x -> y -> y; }
> static<T>
> Function<UnaryOperator<UnaryOperator<Function<T,UnaryOperator<T>>>>,Function<T,UnaryOperator<T>>>
> IS_ZERO() { return n -> n.apply(x -> FALSE()).apply(TRUE()); }
> static<T>
> Function<UnaryOperator<UnaryOperator<Function<T,UnaryOperator<T>>>>,Function<T,UnaryOperator<T>>>
>                IS_ZERO(Class<T> t) { return n -> n.apply(x ->
> FALSE()).apply(TRUE()); }
> static boolean toBoolean(Function<Boolean,UnaryOperator<Boolean>> f) { return
> f.apply(true).apply(false); }
>
>
> Why is this not compiling:
>
> System.out.println(toBoolean(IS_ZERO().apply(ZERO())));
> System.out.println(toBoolean(IS_ZERO().apply(ONE())));
>
> Test.java:18: error: method toBoolean in class Test cannot be applied to given
> types;
>                  System.out.println(toBoolean(IS_ZERO().apply(ZERO())));
>                                     ^
>    required: Function<Boolean,UnaryOperator<Boolean>>
>    found: Function<Object,UnaryOperator<Object>>
>    reason: argument mismatch; Function<Object,UnaryOperator<Object>> cannot be
> converted to Function<Boolean,UnaryOperator<Boolean>>
> Test.java:19: error: method toBoolean in class Test cannot be applied to given
> types;
>                  System.out.println(toBoolean(IS_ZERO().apply(ONE())));
>                                     ^
>    required: Function<Boolean,UnaryOperator<Boolean>>
>    found: Function<Object,UnaryOperator<Object>>
>    reason: argument mismatch; Function<Object,UnaryOperator<Object>> cannot be
> converted to Function<Boolean,UnaryOperator<Boolean>>
> 2 errors
>
> But this works fine:
>
> Function<UnaryOperator<UnaryOperator<Function<Boolean,UnaryOperator<Boolean>>>>,Function<Boolean,
>                      UnaryOperator<Boolean>>> IZ = IS_ZERO();
> System.out.println(toBoolean(IZ.apply(ZERO())));
> System.out.println(toBoolean(IZ.apply(ONE())));
>
> And this works fine:
>
> System.out.println(toBoolean(IS_ZERO(Boolean.class).apply(ZERO())));
> System.out.println(toBoolean(IS_ZERO(Boolean.class).apply(ONE())));
>
>
> Thanks.
>
> - --
> Marc Petit-Huguenin
> Email: marc at petit-huguenin.org
> Blog: http://blog.marc.petit-huguenin.org
> Profile: http://www.linkedin.com/in/petithug
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1
>
> iQIcBAEBCAAGBQJS9kC0AAoJECnERZXWan7E8RoP/ijeRlsqUq0cvaRPLoGwsr4L
> PLZNeV02wyJ6hlE7za7gOaJybpeOlDjZ/ZtK46L+E3WkTCjpidGOwiTK4O84igdq
> TYpIwiCHA4x3KNzqQmeoB8loEYd2RnP7n9RshNziJFjKTodhlvfaJf7WoNmd5SNF
> Gei9IY7rPXOriOVBY/fnfZzC77pG5ATWfgZtVeJrrgPaZs4v+nVZJD26VtRCIGqQ
> qCYF3RrjLNNhc/JSFY+0G421HRiMDnrbYxz2g1j7UmKSRN+NwspiE44EUMS0Wkeo
> RGQFZWVt+dMNanif3YChGLtqsWUcrWXo5BGrY2+I8pxil+MySUQ6bGq4jl+vaclV
> IESDtCKQYnrElB+3mjEC1r5ZlZ/DhqaQY3vLceqh6E1BTZxzoD2f39MgFoZuynrR
> M/Yj2wOcm3EPAwp8wi81qjDWs7b4CdatHyxjSZbzq36p+C9XdmCA87S1W3IIWAay
> UvfsDx3AJFKwX0uk6aH8LDzuPScyNmFmy91uCzI7f9z2AYiPtQrfD3XNgLYYia7d
> 5Y3dUsXUGXZyGiRCvCwDBFDVKtJLatdmbIt2oM0yLqVWuNPCOKwX3hlOoqnalrHi
> t+8BKEqb4ndlxFl6UOUX5AnENApnlAlwAHYLPKrIFbjX1EmsUUUQ7bKilrHCqf6S
> OMe2orq6bDfrceutmQX+
> =7fTh
> -----END PGP SIGNATURE-----
>


More information about the lambda-dev mailing list