В другом месте вы упомянули, что вы новичок в F # (начал изучать его восемь дней назад), поэтому вот краткое руководство по чтению документации по F #, которая может помочь вам самостоятельно ответить на некоторые из этих вопросов.Давайте посмотрим на документацию для модуля Seq
.В нем перечислено множество функций, которые можно вызывать для последовательностей: append
, average
, averageBy
, filter
, map
, groupBy
... Все они имеют разные сигнатуры типов и сигнатуру типакаждой функции является ключом к тому, что она будет делать.Давайте рассмотрим несколько примеров:
average
: seq<^T> -> ^T
- Возвращает среднее значение элементов в последовательности. averageBy
:('T -> ^U) -> seq<'T> -> ^U
- Возвращает среднее значение результатов, полученных при применении функции к каждому элементу последовательности. map
: ('T -> 'U) -> seq<'T> -> seq<'U>
- СоздаетНовая коллекция, элементами которой являются результаты применения данной функции к каждому из элементов коллекции.
Сначала average
, так как это проще всего.Стрелка ->
в типе signure говорит вам, что это функция.Ввод слева от стрелки, а выход справа от стрелки.Таким образом, сигнатура типа означает, что эта функция принимает seq<^T>
и возвращает элемент типа ^T
.Символы ^
или '
перед именем типа T
означают, что это универсальный тип, который будет преобразовываться в любой тип, который у вас есть при запуске кода: int, string, tuple и т. Д.Так что T
- это просто название для любого типа, который у вас есть: если у вас есть целые числа, это функция seq<int> -> int
Если у вас есть строки, это функция seq<string> -> string
и так далее.(Символ ^
перед типом означает, что он будет разрешен во время компиляции, тогда как символ '
перед ним означает, что он будет разрешен во время выполнения. Вам не нужно беспокоиться об этом различиидо тех пор, пока у вас не будет намного больше опыта с F #, а пока просто рассматривайте любой из них как флаг, который означает «Это универсальный тип»).Таким образом, сигнатура типа функции average
говорит вам, что она принимает последовательность значений и возвращает одно значение .
Now, averageBy
.Это сложнее.Во-первых, здесь есть еще стрелки.Это связано с концепцией под названием curry , которая очень хорошо объяснена в ссылке, поэтому я не буду вдаваться в подробности.На начальном уровне вы должны думать о том, что идет после стрелки final , как о выходе функции, а все остальные типы как о входах функции (которые будут разделены стрелками).).Другими словами, подпись типа, подобную int -> char -> string
, должна читаться как «это функция, которая принимает два ввода: int
первый и char
второй и возвращает string
.»
Но видите ли вы круглые скобки вокруг бита ('T -> ^U)
в сигнатуре averageBy
?Эти скобки означают только то, что они имеют в виду в математике: прочитайте эту часть отдельно.Таким образом, первый параметр averageBy
имеет тип ('T -> ^U)
.Второй параметр averageBy
имеет тип seq<'T>
, а вывод имеет тип ^U
.Теперь, если вы посмотрите на сигнатуру типа ('T -> ^U)
, в ней есть стрелка, так что это функция.В частности, это функция, которая принимает вещь универсального типа T
и возвращает вещь универсального типа U
.(Как я уже говорил ранее, не беспокойтесь о различии '
против ^
прямо сейчас).Второй параметр представляет собой последовательность элементов типа T
, а выходные данные имеют тип U
.Эта сигнатура типа плюс имя дает вам подсказку о том, как работает функция: она будет просматривать последовательность вещей типа T
, и для каждого она будет вызывать функцию для преобразования этой вещи T
в вещь типа U
.Затем он возвращает единственное значение U
в качестве выходных данных: по имени вы можете заключить, что единственное значение, которое оно возвращает, будет средним значением всех значений U
, полученных функцией 'T -> ^U
.
Таким образом, сигнатура типа ('T -> ^U) -> seq<'T> -> ^U
означает, что первый аргумент является функцией, которая принимает T
и возвращает U
, второй аргумент представляет собой последовательность элементов типа T
, а функция возвращаетодин элемент типа U
.
Наконец, давайте посмотрим на map
.Его сигнатура типа выглядит довольно похоже на averageBy
: первый параметр снова является функцией, которая принимает T
и преобразует его в U
.Второй параметр снова представляет собой последовательность T
элементов.Но на этот раз вместо одного значения результатом map
будет последовательность из U
значений.
И так, посмотрев документацию , мы можем видеть, что если вы не хотите, чтобы последовательность выводилась, Seq.map
- это неправильная вещь для вызова.В модуле Seq
есть изумительный список функций, так что вы можете быть немного ошеломлены.Но внимательный взгляд на сигнатуры типов и понимание того, что означает каждый из них, - это большая помощь в определении того, кто будет делать то, что вы хотите с вашими данными.И чтение через https://fsharpforfunandprofit.com/posts/list-module-functions/ также поможет вам: F # осторожно рассматривает модули List
, Seq
и Array
как , очень похожие друг на друга , включая почтивсе те же функции.Поэтому, если вы знаете, что делает List.averageBy
, вы также будете знать, что делают Seq.averageBy
и Array.averageBy
: единственная разница будет в том, какой тип коллекции они принимают в качестве входных данных.Поэтому, хотя на этой странице говорится о списках, ее рекомендации также применимы и к Seq.
Кто-то уже ответил на ваш вопрос в комментариях (просто сделайте Seq.map (fun row -> (row.STATE,row.INCOME,row.CHILDREN), 100.0 - float row.otherparty)
, и вы должны получить желаемый результат), поэтомуЯ не буду вдаваться в подробности там.Надеюсь, что время, которое я потратил на написание этой статьи, будет полезно для вас, чтобы помочь вам лучше понять вещи, так что вы сможете ответить на свои вопросы в будущем и вам не придется полагаться на вопрос о переполнении стека (изатем ждем, иногда часы, ответов).