Ошибка синтаксиса Ocaml

Я использую реализацию ленивых списков, где типом может быть Nil или Cons (value, thunk), где thunk - это функция от единицы к остальной части списка.

Я пытаюсь написать функцию cross, которая бы работала так же, как List.combine. К сожалению, у меня есть синтаксические ошибки.

open Sequence;;
    let rec (cross : 'a Sequence.t -> 'b Sequence.t -> ('a * 'b) Sequence.t) = match seq1 with
        Nil -> match seq2 with
            Cons (value2, thunk2) -> Cons ((Nil, value2), function () -> (cross Nil (thunk2 ())))
      | Cons (value1, thunk1) -> match seq2 with
            Nil -> Cons ((value1, Nil), function() -> (cross Nil (thunk1 ())))
          | Cons (value2, thunk2) -> Cons ((value1, value2), function() -> (cross (thunk1 ()) (thunk2 ())))

Это вызывает ошибку:

Error: Unbound value seq1

Что я делаю неправильно?

ОБНОВЛЕНИЕ:

Этот тип проверяет, но не тот, который я ищу.

let rec cross (seq1 : 'a Sequence.t) (seq2 : 'b Sequence.t) : ('a * 'b) Sequence.t = match seq1 with
    Nil -> match seq2 with
        Cons (value2, thunk2) -> Cons ((Nil, value2), function () -> (cross Nil (thunk2 ())))
  | Cons (value1, thunk1) -> match seq2 with
        Nil -> Cons ((value1, Nil), function() -> (cross Nil (thunk1 ())))
      | Cons (value2, thunk2) -> Cons ((value1, value2), function() -> (cross (thunk1 ()) (thunk2 ())))

val cross :
  'a Sequence.t Sequence.t ->
  'a Sequence.t Sequence.t -> ('a Sequence.t * 'a Sequence.t) Sequence.t =
  <fun>

Это не тот крест, который мне нужен. Я ищу:

'a Sequence.t -> 'b Sequence.t -> ('a * 'b) Sequence.t

person Nick Heiner    schedule 29.10.2009    source источник
comment
Ошибка какого типа вы получаете? Разве вы не должны сопоставить с Sequence.Nil и Sequence.Cons?   -  person nlucaroni    schedule 29.10.2009
comment
Я использовал open Sequence ;; дальше вверх по файлу. отредактирован, чтобы включить это.   -  person Nick Heiner    schedule 29.10.2009
comment
Что кросс пытается сделать? (я думаю, что меня сбили с толку такие функции как List.combine, вы пытаетесь объединить 2 последовательности?)   -  person LB40    schedule 29.10.2009
comment
Вы также должны опубликовать код для thunk1.   -  person LB40    schedule 29.10.2009


Ответы (4)


ты собираешься пнуть себя ... где определяется seq1?

let rec (cross : 'a Sequence.t -> 'b Sequence.t -> ('a * 'b) Sequence.t) =

Вы определяете тип креста, но не привязываете переменные ни к чему (я думаю, вы можете так сказать).

let rec cross (seq1:'a Sequence.t) (seq2:'a Sequence.t) :('a * 'b) Sequence.t =

РЕДАКТИРОВАТЬ:

Я думаю, что ваше соответствие хорошее, неверное. Используйте блоки begin ... end вокруг случаев, я думаю, что происходит (и поскольку у меня нет Sequence, я не могу проверить), это то, что случаи совпадения, которые вы намереваетесь для внешнего совпадения, применяются к внутреннему, соответствуя seq2. Например,

match x with
| 0 -> match y with
    | 1 -> "x:0, y:1"
| 2 -> match y with
    | 0 -> "y:0, x:2"

Хотя пространственно это выглядит нормально, второе совпадение, match y with, связано с регистром совпадений | 2 -> .... Вот версия с being ... end ключевыми словами, окружающими варианты соответствия. Второе начало ... конец не нужно, но, вероятно, все равно будет неплохо сделать это для ясности.

match x with 
| 0 -> begin match y with
    | 1 -> "x:0, y:1" end
| 2 -> begin match y with
    | 0 -> "y:0, x:2" end
person nlucaroni    schedule 29.10.2009
comment
+1: Я получил +1, пока мой ответ был более свежим (на пару секунд, но все же ...). - person LB40; 29.10.2009

в первой строке вы пытаетесь сопоставить с seq1, но это значение не привязано, что означает, что его нигде нет.

Это точно так же, как:

# let t =
  match t1 with
  _ -> ();;
Error: Unbound value t1

Вы должны назвать свои аргументы.

person LB40    schedule 29.10.2009

Для вашего обновленного вопроса причина типов 'a Sequence.t Sequence.t связана с строкой

Cons ((Nil, value2), ...)

Напомним, что Nil - это сама последовательность, поэтому, помещая это туда, он заставляет все элементы входных последовательностей также быть последовательностями.

person newacct    schedule 29.10.2009
comment
хорошо, тогда как мне выразить ('a *' b), не создавая последовательности обоих элементов? - person Nick Heiner; 30.10.2009
comment
@Rosarch: Ну, я не знаю; потому что нет очевидного способа выразить пустое значение. Позвольте мне спросить вас: предположим, вы хотите написать эту функцию для обычных списков, т.е. вы хотите создать функцию, которая представляет собой список - ›'b list -› (' a * 'b) list. Как бы ты это сделал? Как бы вы работали со списками разной длины? - person newacct; 30.10.2009
comment
@newacct +1: List.combine не обрабатывает списки разной длины, у вас есть InvalidArgument. Я действительно не знаю, что вы можете сделать, так как пустого значения нет. Неплохо подмечено. :-) - person LB40; 30.10.2009

Эта ошибка возникает, когда вы упомянули имя, которое не было определено (технически «привязано к значению»). Это могло произойти, если вы неправильно набрали имя.

person Rishabh Agarwal    schedule 27.07.2015