Предполагая, что list_min
определено, вы должны думать о проблеме методично.Допустим, вы представляете набор со списком.Ваша функция принимает этот набор и некоторые аргументы и возвращает подмножество исходного набора, если элементы удовлетворяют определенным условиям.
Теперь, когда я впервые прочитал это, List.filter
автоматически пришло мне в голову.
List.filter : ('a -> bool) -> 'a list -> 'a list
Но вы хотели изменить m
, чтобы это было бесполезно.Важно знать, когда вы можете использовать библиотечные функции и когда вам действительно нужно создавать свои собственные функции с нуля.Вы можете четко использовать filter
при обработке m
в качестве ссылки, но это не будет функциональным способом.
Сначала давайте сосредоточимся на вашем предикате:
fun s d m e -> (float e) > (1. +. d)*.(float m) && (e <= s)
Обратите внимание, что +.
и *.
- это функции плюс и произведение для чисел с плавающей точкой, а float
- это функция, которая переводит целое число в число с плавающей точкой.
Скажем, функция predicate
- это предикат, который я только что упомянул.
Теперь это тоже вопрос мнения.По моему опыту я бы не стал использовать fold_left
только потому, что это просто сложно и не нужно.
Итак, давайте начнем с моего представления о коде:
let m = list_min l;;
Так что это начальныйm
Затем я определю вспомогательную функцию, которая читает m
в качестве аргумента, с l
в качестве исходного набора, а s
, d
и m
переменные, которые выиспользуется в вашем исходном императивном коде.
let rec f' l s d m =
match l with
| [] -> []
| x :: xs -> if (predicate s d m x) then begin
x :: (f' xs s d x)
end
else
f' xs s d m in
f' l s d m
Затем для каждого элемента вашего набора вы проверяете, удовлетворяет ли он предикату, и если это так, вы вызываете функцию снова, но заменяете значение * 1041.* с x
.
Наконец, вы можете просто вызвать f'
из функции f
:
let f (l: int list) (s: int) (d: float) =
let m = list_min l in
f' l s d m
Будьте осторожны при создании такой функции, как list_min
, что быпроизойдет, если список был пуст?Обычно вы используете тип Option
для обработки этих случаев, но вы предполагаете, что имеете дело с непустым набором, так что это здорово.
При функциональном программировании важно думать о функциональности.Сопоставление с образцом супер рекомендуется, в то время как указатели / ссылки должны быть минимальными.Я надеюсь, что это полезно.Свяжитесь со мной, если у вас есть другие сомнения или рекомендации.