Search code examples
syntaxocamllazylist

Ocaml Syntax Error


I'm using an implementation of lazy lists where the type can be either Nil or Cons (value, thunk), where thunk is a function from unit to the rest of the list.

I'm trying to write a function cross, which would function as List.combine does. Unfortunately, I'm having syntax errors.

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

This produces the error:

Error: Unbound value seq1

what am I doing wrong?

UPDATE:

This type checks, but is not of the type I'm looking for.

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>

This is not the type of cross that I want. I'm looking for:

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

Solution

  • you are going to kick yourself... where is seq1 defined?

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

    You define the type of cross, but you don't bind the variables to anything (I guess, you can say that).

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

    EDIT:

    I think your matching is well, mis-matched. Use begin ... end blocks around the cases, I think what is happening (and since I don't have Sequence, I cannot verify) is that the match cases you intend for the outer match are being applied to the inner one, matching seq2. for example,

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

    Although, spatially, it looks fine, the second match, match y with is bound with the | 2 -> ... match case. Here is a version with the being ... end keywords surrounding the match cases. The second begin ... end isn't needed, but it's probably a good idea to do it anyway for clarity.

    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