Лямбда F #: получение минимального значения из списка независимо от того, является ли ввод строковым или целым - PullRequest
0 голосов
/ 05 ноября 2018

Я создал вспомогательную функцию папки, чтобы помочь с моим проектом

let rec fold f v xs =
    match xs with 
    | [] -> v
    | (x::xs) -> f (x) (fold f v xs )

и теперь мне нужна функция, которая помогает мне получить минимальное значение из списка, но я не хочу использовать итерацию или рекурсию. Я придумал следующее:

let min l = fold (fun acc -> min acc) System.Int32.MaxValue l

протестировал функцию в списке целых чисел min [4;2;3;34;] и получил ожидаемый желаемый результат:

val min : l:int list -> int
val it : int = 2

Теперь, как бы мне сделать так, чтобы эта функция применялась и к строкам? Например min ["do"; "je"; "ca"; "ja"] это "ca" Я стараюсь избегать использования встроенных функций List с целью заставить себя использовать вспомогательные функции и лямбды. Любая помощь будет оценена

1 Ответ

0 голосов
/ 05 ноября 2018

Чтобы ваша функция min работала как с целыми числами, так и с числами, вам нужно две вещи:

  • Сделайте это inline, чтобы компилятор F # мог использовать статические ограничения членов (что будет означать, что он может работать со значениями любого типа, поддерживающего сравнение)

  • Избавьтесь от константы Int32.MaxValue, поскольку это ограничивает тип только целыми числами.

Первый - это просто добавление ключевого слова inline. Во-вторых, вы можете передать максимальную строку (но на самом деле такой вещи не существует). Лучше всего взять первый элемент в качестве начального значения и запустить fold для остальных. Поскольку min не может работать с пустыми списками, вы можете выдавать исключения, когда список пуст:

let inline min l = 
  match l with 
  | x::xs -> fold min x xs
  | [] -> invalidArg "l" "Cannot get minimum of empty list!"

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

min [4;2;3;34;]    
min ["do"; "je"; "ca"; "ja"]
...