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 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 T
and a list of T
s. 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 T
s, the result will be a T
. But clearly the result of reversing a list of T
s should be another list of T
s, not a plain T
.
If you want to reverse a list using a fold and cons, you'll need to define it in terms of foldl
, not foldl1
. foldl
allows for the result type to be different from the element type of the list and it allows you to use something other than the first element of the list as the starting value of the accumulator (which you need because, as I said, the accumulator needs to be a list).