#functional-programming #f#
#функциональное программирование #f#
Вопрос:
Я довольно новичок в F # и списках обучения.Мне трудно реализовать свою собственную функцию уменьшения. Я застрял, пытаясь реализовать это. Это то, что у меня есть до сих пор, но я получаю сообщение об ошибке, которое при вызове reduce говорит, что список, который я передаю, является типом типа int, но должен быть типа ‘список. Я был очень разочарован этим, поэтому любая помощь приветствуется.
Вот как выглядит мой код:
let reduce Fn (list: 'a list) =
let rec innerFun list acc =
match list with
| (x::xs) :: xss ->
let newAcc = Fn x xs // the fn applied to the head and the next element
innerFun xss newAcc // recurse through the list with new accumulator
| [] -> acc // if the list is empty return the accumulator
innerFun list 0
//Calling reduce
let red2 = reduce (fun x y -> x*y) [23; 4]
Комментарии:
1. Вам не хватает части определения функции в примере?
2. Дал вам ответ о проблеме, которую вы видите, но в вашей реализации есть несколько вещей, которые отсутствуют. Сравните его поведение со встроенным
List.reduce
, особенно для пустых и одноэлементных списков.
Ответ №1:
Непосредственная проблема, с которой вы сталкиваетесь, на самом деле довольно проста и чисто синтаксическая:
match list with
| (x::xs) :: xss ->
Круглые скобки делают так, чтобы шаблон соответствовал списку списков, т. Е. x::xs
Является головным элементом списка, а x
and xs
соответственно являются его головой и хвостом.
Вам нужно сопоставить два элемента в начале списка — вам нужно удалить скобки:
match list with
| a::b::tail ->
Обратите внимание, что в соглашении об именах, которое вы используете, уже есть подсказка — s
in xs
означает множественное число — поэтому в этом шаблоне вы разбиваете список на начало «ex» и конец «exes».
Комментарии:
1. Большое спасибо! Это очень полезно! Еще один вопрос, который у меня также возник, заключается в том, как я мог бы использовать функцию reduce в любом типе? Поскольку я передаю int 0 в качестве начального накопителя, результатом всегда будет некоторый int, но, допустим, я хочу выполнить свою функцию reduce для других типов, таких как строки или символы? Есть ли способ, которым я мог бы создать универсальный аккумулятор? Еще раз спасибо
2. Вот о чем мой другой комментарий — обычно reduce не нуждается в этом явном начальном значении и, как ожидается, завершится ошибкой при пустом вводе. Вы могли бы сделать это начальное значение явным и превратить его в аргумент для функции, но в этот момент вы фактически реализуете
fold
.