Как уже упоминалось Vidas, вы можете просто использовать встроенную функцию List.length
, которая является лучшим способом сделать это на практике. Однако, если вас интересуют дополнительные параметры, тогда основной альтернативой является использование рекурсии:
let rec length l =
match l with
| [] -> 0
| x::xs -> 1 + (length xs)
Это не написано с использованием комбинаторов, но это основной функциональный шаблон. Общий шаблон функции фиксируется функцией fold
, которая позволяет (в основном) указать две ветви сопоставления с шаблоном. Используя fold
вы можете написать:
let list1 = [ 10; 25; 34; 45; 78 ]
List.fold (fun s x -> s + 1) 0 list1
Это говорит о том, что начальное состояние 0
, и для каждого элемента мы увеличиваем состояние s
на 1
- так что результатом будет длина списка.
Если вы хотите сделать что-то совершенно безумное, вы можете попробовать заменить функцию fun s x -> s + 1
на функцию, составленную с использованием комбинаторов. Это сделает ваш код нечитаемым (и никто никогда не должен этого делать), но интересно подумать, как это сделать. Вам может понадобиться вспомогательная функция, которая принимает функцию, два аргумента и передает два аргумента функции в виде кортежа:
let tuple f = fun a b -> f (a, b)
Теперь вы можете написать что-то вроде приведенного ниже кода - который использует как можно больше стилей комбинаторов, но его довольно сложно расшифровать.
List.fold (tuple (fst >> (+) 1)) 0 list1
Итак, List.length
- это путь: -).