Понимание структуры Ocaml - PullRequest
       12

Понимание структуры Ocaml

0 голосов
/ 18 марта 2019

Как я прохожу через сайт: http://www.cs.princeton.edu/courses/archive/fall14/cos326/sec/03/precept03_sol.ml

У меня вопрос по структуре Ocaml. Если быть более конкретным, у меня есть вопросы по коду:

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);;

Что делает f hd в самой последней строке? (Я понимаю, что reduce f u tl снова вызывает саму функцию.)

Мой второй вопрос - как использовать функцию для реализации другой функции в Ocaml. Для кода:

let times_x (x: int) (lst: int list) : int list =  
  map (fun y -> y*x) lst

Что делает fun y -> y*x? что делает lst в конце кода?

Спасибо за помощь!

1 Ответ

1 голос
/ 18 марта 2019

Предоставленный код представляет собой функцию сокращения, которая принимает три параметра - функцию, которая отображает входные данные типа '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 в целом.

Я надеюсь, что этот ответбыл адекватен при решении вашего вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...