F# уменьшить функцию в списке кортежей

Этот простой кусок кода ставит меня в тупик

Так что это работает

> let l = [1; 2; 3; 4];;
val l : int list = [1; 2; 3; 4]
> List.reduce(fun accm i -> accm + i) l;;
val it : int = 10

Но это не так (хотя логика точно такая же)

> let l = [("a", 1); ("b", 2); ("c", 3); ("d", 4)];;                         
val l : (string * int) list = [("a", 1); ("b", 2); ("c", 3); ("d", 4)]       

> List.reduce(fun accm tup -> accm + (snd tup)) l;;                          
List.reduce(fun accm tup -> accm + (snd tup)) l;;        

>stdin(46,47): error FS0001: The type 'int' does not match the type 'string * int'

Почему я получаю эту ошибку, потому что код прост. итерируйте по списку, возьмите кортеж и передайте его функции сокращения вместе со значением аккумулятора.

внутри функции возьмите второе значение из кортежа и добавьте его в аккумулятор.

Я знаю, что может быть много других способов получить то, что я хочу... но я хочу знать, почему приведенный выше код не работает?

3 ответа

Решение

reduceАргументы должны иметь одинаковый тип и элементы списка (в данном случае тип кортежа), но вы пытаетесь добавить один во вторую половину другого.

Вам необходимо указать начальное значение. Если нет начального значения, то reduce принимает первое значение в List это начальное значение, которое является кортежем. Отсюда и ошибка, которую вы получаете.

Я думаю, что вы пытаетесь сделать, это List.sumBy snd,

reduce Предполагается, что аккумулятор относится к тому же типу, что и элемент списка, что не является допущением, которое делает функция редуктора в вопросе.

Другие вопросы по тегам