Jas - 3 months ago 17

Scala Question

in insufficiently-polymorphic

why did the author add the 3rd argument:

`bbb: B => B => B`

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`

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.