Я пытаюсь добавить кортеж в список на Ocaml - PullRequest
0 голосов
/ 09 декабря 2018

Я пытаюсь добавить кортеж типа (int * int) для цикла for в список, но я получаю сообщение об ошибке: это выражение должно иметь тип блока.

это то, что у меня сейчас:

let addtuple k lst =
  for i=0 to k - 1 do 
    let (n,j) =Scanf.scanf " %d %d" (fun a b->(a,b))
 in
      (n,j)::lst
    done;;

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

С for необходимо использовать ref:

let addtuple k lst = 
  let r = ref lst in
    for i = 1 to k do
      r := (Scanf.scanf " %d %d" (fun x y -> (x, y))) :: !r
    done;
    !r;;

Более функциональный подход с использованием рекурсивной функции:

let rec addtuple k lst =
  match k with
  | 0 -> lst
  | _ -> addtuple (k - 1) ((Scanf.scanf " %d %d" (fun x y -> (x, y))) :: lst);;
0 голосов
/ 09 декабря 2018

Цель OCaml for - сделать что-то, а не вычислить значение.Таким образом, тело цикла должно быть выражением OCaml, которое имеет полезный побочный эффект (например, печать значения).По этой причине тело цикла for должно иметь тип unit, тип, используемый для выражений, которые не имеют интересного значения.Но у вашего цикла есть тело, которое является списком.Компилятор говорит вам (правильно), что это указывает на то, что что-то не так.

Ваш код написан в предположении, что выражение (n, j) :: lst изменит значение lst.Но это не так.В функциональном языке, таком как OCaml, вы не можете изменять значения переменных.

Если ваша функция должна возвращать список, она не может быть основана на цикле for, который всегда возвращает () (уникальное значение типа unit).Скорее всего, это должно быть основано на сгибе (который накапливает значение при работе через серию входов) или на вашей собственной рекурсивной функции.

...