The reason that you can't pass cons as an argument to foldl1 without casting is that the type of cons simply does not match that of foldl1's function argument and your cast is in fact is illegal - but, sadly, unchecked, so you don't get an exception right away (you will get one eventually though).
You've defined foldl1 to take a function that takes two arguments of the same type and cons doesn't do that. Cons takes a list of Ts and a T. When foldl1 first calls cons, it will call it with the list's first and second elements as arguments. Since neither of those is a list, this will cause a ClassCastException to be thrown.
So cons is simply not a valid argument for foldl1
. Not only is there no way to avoid the cast, there's also no way to make the cast actually work.
Another reason that you can't use foldl1 to reverse a list is its return type: foldl1 returns a T where T is the element type of the list you're calling it on. So if you use foldl1 on a list of Ts, the result will be a T. But clearly the result of reversing a list of Ts should be another list of Ts, not a plain T.
If you want to reverse a list using a fold and cons, you'll need to define a proper foldl function - not foldl1. That is you need to define a foldl function whose function argument accepts two arguments of (possibly) different types and which takes a third argument specifying the starting value of the accumulator.