In Haskell, using GADTSyntax, it would be something like
data Collector a b where
MakeCollector :: (x -> a -> x) -> x -> (x -> b) -> Collector a b
That is: to construct a collector that ingests as and returns a single b, you need to supply a step function, the initial state of type x, and a "tally" function that calculates the result b from the final state. The type of the state ("x") is not present in the type "Collector a b"; it is an "existential".In the Java Collectors framework, this is (roughly) analogous to
Collector.of (Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Collector.Characteristics... characteristics)
And the type parameter that corresponds to the existential in Haskell is: A - the mutable accumulation type of the reduction operation (often hidden as an implementation detail)