Jas Jas - 1 month ago 9
Scala Question

in insufficiently-polymorphic why do we need the `bbb: B => B => B`?

in insufficiently-polymorphic

why did the author add the 3rd argument:

bbb: B => B => B
what does it mean from b to b to b, why do we need such a thing?


Let’s say we take this one step further and introduce even more
polymorphism into the code, hiding the fact that the second parameter
and return values are lists:


foo :: forall a b. List a -> (a -> b) -> (b -> b -> b) -> b -> b
def foo[A, B](as: List[A], b: B, ab: A => B, bbb: B => B => B): B


and why is there suddenly a conversion function from a to b:
ab: A => B
we didn't have that in original code, why was it added?

Lee Lee
Answer

This is hinted at later in the post with the further generalised version:

foo :: forall f a r. (Foldable f, Semigroup r) => f a -> (a -> r) -> r -> r

A semigroup is just a structure which supports a binary append operation e.g.

trait Semigroup[T] {
    def append(v1: T, v2: T): T
}

So foo takes an input list, a function to map each list element to some appropriate semigroup instance (the function a -> b and an append operation for the semigroup. The final b parameter is the initial value to accumulate.

foo then simply iterates over the list combining the current accumulator with the value associated with the current list item e.g.

def foo[A, B](as: List[A], b: B, ab: A => B, bbb: B => B => B): B = 
    as.foldLeft(b)((acc, e) => bbb(ab(e), acc))

Lists form a semigroup where append just appends the two lists.