OCaml: функция pell со списками int

Я пытаюсь написать простую функцию в OCaml.

let rec pell (i: int) =
(if i <= 2 then i (*if given n is less tahn 2 then return 2, else return previous n-1 th term and n-2 nd term recursively*)
  else if i>2 then
  2 * pell i - 1 + pell i - 2

else failwith "unimplemented" (*else fail with unimplemented message*)
);;

Напишите версию функции pell с бесконечной точностью из предыдущего

pell2 0 = []

pell2 1 = [1]

pell2 7 = [9; 6; 1]

pell2 50 = [2; 2; 5; 3; 5; 1; 4; 2; 9; 2; 4; 6; 2; 5; 7; 6; 6; 8; 4]

Я написал ниже код для этого:

let rec pell2 i =

(if i <= 2 then
  [] -> i;
  else if i=0 then [];
  else if i>2 then                                (*finding pell number and using sum function to 
output list with infinite precision...*)
  [] -> pell2 i-1 + pell2 i-2;

else failwith "unimplemented"

);;

но все еще имеет некоторые синтаксические ошибки. Может кто-нибудь помочь мне с этим, пожалуйста.


person Vicky    schedule 25.02.2021    source источник
comment
Что это ->? Откуда n?   -  person Lhooq    schedule 25.02.2021


Ответы (2)


if i <= 2 then
     [] -> i

В подобных фрагментах -> недействителен. Похоже, вы можете смешивать сопоставление с образцом с match ... with ... и if/else up.

Кроме того, сначала вы проверяете, меньше ли i 2 или равно ему, но затем у вас есть else, чтобы проверить, равен ли i нулю. Первая проверка означает, что второй никогда не произойдет.

person Chris Dutton    schedule 25.02.2021
comment
О, да. ляп я бы поправил. Я просто хочу добавить значения в список в 1-й и последней строке. - person Vicky; 25.02.2021

Во-первых, давайте посмотрим на примеры вывода pell2. Мы видим, что pell2 имеет единственный целочисленный параметр и возвращает список целых чисел. Итак, мы знаем, что функция, которую мы хотим создать, имеет следующую сигнатуру типа:

pell2: int -> int list

Исправление (некоторых, но не всех) синтаксических ошибок и попытка сохранить вашу логику,

let rec pell2 i =
  if i=0 then []
  else if i <= 2 then i
  else if i>2 then pell2 i-1 + pell2 i-2

Обратите внимание, что я удалил точку с запятой в конце каждого выражения, так как OCaml использует точку с запятой в своем синтаксисе специально для работы с выражениями, оценивающими единицу измерения (). См. отличное объяснение ivg. Главный недостаток этого кода в том, что он не печатает проверку. Мы видим, что мы условно возвращаем список, а в противном случае возвращаем int. Обратите внимание, как выше мы определили, что pell2 должен возвращать int list. Итак, мы можем начать исправлять это, обернув наши результаты int в список:

let rec pell2 n = 
  if n = 0 then []
  else if n <= 2 then [n]
  else ... something that will return the Pell number as a list ...

Как вы уже писали, ветку else можно написать с помощью рекурсивных вызовов функции pell2. Однако мы не можем записать его так, как вы делали ранее, потому что pell2 оценивается как список, а бинарный оператор + работает только с двумя целыми числами. Итак, нам нужно будет определить собственный способ суммирования списков. Назвав это sum_lists, мы получим следующий код: Теперь мы можем полностью определить нашу функцию pell2:

let rec pell2 n =
  if n = 0 then []
  else if n <= 2 then [n]
  else (* Pell(n) = (2 * Pell(n-1)) + Pell(n-2) *)
    let half_of_first_term = pell2 n-1 in
    let first_term = sum_lists half_of_first_term half_of_first_term in
    let second_term = pell2 n-2 in
    sum_lists first_term second_term

Итак, все, что осталось, — это определить sum_lists, чтобы мы правильно суммировали вместе два списка того же формата, что и возвращаемый тип pell2. Подпись для sum_lists будет

sum_lists: int list -> int list -> int list

Я дам базовую схему реализации, но оставлю остальное на ваше усмотрение, так как это основная проблема задачи назначения.

let sum_lists lst1 lst2 =
  let rec sum_lists_helper lst1 lst2 carry =  
    match lst1, lst2 with
    | [], [] -> if carry = 1 then [1] else []
    | h::t, []
    | [], h::t -> ...
    | h1::t1, h2::t2 -> ...
  in
  sum_lists_helper lst1 lst2 0
person EliKor    schedule 25.02.2021