Предоставленный код представляет собой функцию сокращения, которая принимает три параметра - функцию, которая отображает входные данные типа 'a
и 'b
на выходные данные типа 'b
, значение типа 'b
икак список элементов типа 'a
.
Например, length
пример из лекции:
let length (lst: int list) : int =
reduce (fun _ len -> len + 1) 0 lst
Первый параметр для reduce
- это функция, которая при задании двух параметров отбрасывает первый и возвращаетвторой параметр увеличивается на единицу.Второе значение (0), которое будет использоваться в качестве аккумулятора.Третий - список для определения длины.
Поведение этой рекурсивной функции reduce
состоит в том, чтобы возвращать второй параметр (аккумулятор, используемый в примере длины), как только предоставленный список пуст, ив противном случае запустите предоставленную функцию, используя заголовок списка и рекурсивное значение.
Еще раз перейдя к примеру length
, скажем, мы даем ему список с одним элементом [1]
.
Наш вызов length
становится reduce (fun _ len -> len + 1) 0 [1]
Recall reduce
:
let rec reduce (f:'a -> 'b -> 'b) (u:'b) (xs:'a list) : 'b =
match xs with
| [] -> u
| hd::tl -> f hd (reduce f u tl);;
Сначала мы сопоставляем [1]
с []
, что не удается,Поскольку это непустой список, мы запускаем f hd (reduce f u tl)
Напомним, что f
- это параметр, предоставленный length
: fun _ len -> len + 1
Следовательно, мы эффективно запускаем следующее:
(fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 [])
В этом случае функция length
отбрасывает первый параметр, поскольку значения в списке не нужны для определения длины списка.
Рекурсивная часть будетсопоставить с []
и вернуть значение u
в то время, которое равно 0.
Следовательно, на один уровень вверх, (fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 [])
становится (fun _ len -> len + 1) 1 0
и возвращает 0 + 1
, что упрощает наши ожиданиязначение 1, представляющее длину списка.
Теперь ко второму вопросу относительно times_x
.Это выполняет сопоставление.Например, мы можем сопоставить [1;2;3;4;5]
с [3;6;9;12;15]
с отображением fun x -> x * 3
.
Здесь times_x
определяется следующим образом:
let times_x (x: int) (lst: int list) : int list =
map (fun y -> y*x) lst
times_x
принимает целое числои список.Используя приведенный выше пример, мы можем вызвать его с помощью times_x 3 [1;2;3;4;5]
, чтобы получить [3;6;9;12;15]
.
Помимо этого, я рекомендую изучить, как работают функции map и Reduce в целом.
Я надеюсь, что этот ответбыл адекватен при решении вашего вопроса.