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