F # Добавить элемент, созданный в для l oop в список - PullRequest
0 голосов
/ 19 февраля 2020

Я хочу добавить элемент в список. Элементы будут созданы внутри a для l oop. Сейчас у меня есть

let MaxCubeVolume tpList = 
    let list1 = [] 
    printfn "%A" list1 
    for l,w,h in tpList do
        let vol = CubeVolume l w h 
        let list = vol::list1
        printfn "%A" list 

Где list1 - это основной список, к которому я пытаюсь добавить, а list - это то, что я пытаюсь использовать для добавления в этот список. CubeVolume работает, он принимает 3 числа с плавающей точкой и возвращает объем куба. tpList - это список кортежей, которые содержат 3 числа с плавающей точкой. Где я теряюсь, это как добавить том в основной список?

Ответы [ 2 ]

4 голосов
/ 19 февраля 2020

F # списки неизменны. Вы не можете "изменить" их. Вы не «добавляете» элементы к ним. Вы можете создать только новый список из старого (но старый остается неизменным и все еще доступным для использования).

Но это неправильное мышление для функционального программирования. В функциональном программировании вы не вычисляете результат путем многократного изменения структур данных. Вместо этого вы создаете большие структуры данных из меньших или используя (и составляете) примитивные функции, которые делают это за вас.

В частности, если у вас есть список, скажем, гипотетически, троек и у вас есть функция, которая может преобразовать одну такую ​​тройку, скажем, гипотетически, в число, и вы хотите составить список этих чисел - это очень хорошо известная примитивная операция с именем map:

let tripleToNumber (l, w, h) = CubeVolume l w h
let list1 = List.map tripleToNumber tpList

Или вы можете указать встроенную функцию преобразования, не назначая ей отдельное имя:

let list1 = List.map (fun (l, w, h) -> CubeVolume l w h) tpList

И затем вы можете использовать оператор |> для изменения параметров List.map, просто чтобы сделайте так, чтобы это выглядело немного лучше:

let list1 = tpList |> List.map (fun (l, w, h) -> CubeVolume l w h)

Или, в качестве альтернативы, вы можете использовать списки F #, которые являются syntacti c sugar: они делают то же самое под капотом, но имеют ( возможно) лучше посмотреть:

let list1 = [for (l, w, h) in tpList -> CubeVolume l w h]

Здесь важно отметить, что ни один из приведенных выше фрагментов на самом деле не изменяет любые данные на месте. Оба они генерируют новое значение путем преобразования старого.

0 голосов
/ 19 февраля 2020

В дополнение к ответу Федора (который является довольно исчерпывающим), общее решение F # для того, что вы назвали своей функцией (поиск максимального значения результата вычисления последовательности), будет состоять в составлении map и max функции. Эти функции существуют в стандартных модулях сбора F # (Seq, List и Array), и вы можете связать их вместе, используя оператор |>:

let maxCubeVolume tpList = 
    tpList |> Seq.map (fun (l,w,h) -> CubeVolume l w h) |> Seq.max

Вы также можете составить их вместе, используя вместо этого оператор >>:

List.map (fun (l,w,h) -> CubeVolume l w h) >> List.max

В стандартных коллекциях F # есть также встроенная функция maxBy, которая возвращает элемент в коллекции, который имеет максимальное значение для данной функции. , Это вернет сам куб (куб с максимальным объемом), а не вычисленное значение для объема. Вот пример использования Seq (самый общий из типов коллекции F #):

let maxCubeVolume tpList = 
    tpList |> Seq.maxBy (fun (l,w,h) -> CubeVolume l w h)
...