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
Предполагается, что аккумулятор относится к тому же типу, что и элемент списка, что не является допущением, которое делает функция редуктора в вопросе.