Question

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
Was it helpful?

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

OTHER TIPS

in the first line, you're trying to match against seq1, but this value is unbound meaning that it's nowhere to be found.

That's exactly the same as :

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

You have to name your arguments.

For your updated question, the reason the types are 'a Sequence.t Sequence.t is because of the line

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

Recall that Nil is a sequence itself, so by putting that there it forces all the elements of the input sequences to be sequences too.

This error occurs when you have mentioned a name which has not been defined (technically “bound to a value”). This might happen if you have mistyped the name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top