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