- A+

I have a problem with the following function

`sum f l1 l2 = (f l1) + (f l2) `

It doesn't work with `sum length [1,2] ['a','b']`

. When I try this I get

`No instance for (Num Char) arising from the literal ‘1’ `

error so the problem is with types. When I try `:t`

function, I get `sum :: Num a => (t -> a) -> t -> t -> a`

. So, if I understand this correctly, I can't just use `+`

function with both numerical and character values at the same time but I lack the deeper understanding of why exactly is this the case and how to fix it.

I tried a couple of things, like using `let`

for one of the literals or `id`

function, but this doesn't seem to work. Any help?

When inferring types from your code, GHC will assume that you intend `f`

to have a relatively simple type, and intend `l1`

and `l2`

to have the same type, so that both are suitable as input to `f`

.

You apparently want to pass a polymorphic `f`

, that can work on both `[Int]`

and `[Char]`

. Depending how general you want to get, here are some options:

Works on lists, `f`

must work on any list regardless of element type:

`sum0 :: (forall x. [x] -> Int) -> [a] -> [b] -> Int sum0 f l1 l2 = f l1 + f l2 `

Works on lists & other `Foldable`

types (Vector, Set, Matrix), as long as both inputs are the same `Foldable`

. The first argument can be `length`

, or something specific to the choice of `Foldable`

, like `Set.size`

.

`sum1 :: (Num n, Foldable f) => (forall x. f x -> n) -> f a -> f b -> n sum1 f l1 l2 = f l1 + f l2 `

Allow `l1`

and `l2`

to be *different* `Foldable`

types. `f`

must work for *any* foldable. `length`

still qualifies, but `Set.size`

isn't general enough.

`sum2 :: (Num n, Foldable s, Foldable t) => (forall f x. Foldable f => f x -> n) -> s a -> t b -> n sum2 f l1 l2 = f l1 + f l2 `

In practice, with a function this small, I think it's easier just to write `length l1 + length l2`

at each use site than to define a function with any of the complex types above. But it's nice to know we can write these types when we want to.