I would like to have a map2 function for Base.Sequence. I can write a sort of version like this:
open Base.Sequence
let map2 f s1 s2 = map ~f (zip s1 s2)
where zip creates a sequence of pairs from elements of s1 and s2, so that map2 has the signature
('a * 'b -> 'c) -> 'a S.t -> 'b S.t -> 'c S.t
However, it seems unnecessary to create pairs just to pull them apart, and in any event I feel that a more natural signature is
('a -> 'b -> 'c) -> 'a S.t -> 'b S.t -> 'c S.t
I have have not figured out a way to write the latter function. I can pull apart sequences using hd and tl, but I can’t figure out how to build sequences one element at a time. There’s nothing like a cons function afaics, and the Sequence constructor that is used to build sequences isn’t visible outside the source file–or at least, I can’t figure out how to use it in my code. I get Error: Unbound constructor Sequence no matter what I try. I think this has to do with the type definitions and signatures in the sequence.ml
(* 'a is an item in the sequence, 's is the state that will produce the remainder of the
sequence *)
type +_ t =
| Sequence : 's * ('s -> ('a,'s) Step.t) -> 'a t
type 'a sequence = 'a t
vs. sequence.mli files, although I’m not sure understand the .ml and .mli type code fully.
Is there any way to build sequences step by step (whether by accessing the Sequence constructor or not), or some other way to write a function like map2, without modifying sequence.ml and rebuilding Base? (Maybe I would have trouble writing the function anyway, but at this point, I can’t even get past the Unbound constructor error.)
(At one point I thought I could use Base.Seq.Step to implement map2, but now I don’t think that made sense; the Yield constructor doesn’t expect a function to return the rest of the sequence; it just wants code to compute part of the next element. This is what I tried:
# let rec map2 f xs1 xs2 =
match xs1, xs2 with
| (Done, _) | (_, Done) -> Done
| (Yield (x1, rest1), Yield (x2, rest2)) ->
Yield ((f x1 x2), map2 f rest1 rest2)
| (Skip _, _) | (_, Skip _) -> failwith "Skip-handling not implemented";;
Error: This expression has type 'a but an expression was expected of type ('b, 'a) S.Step.t
The type variable 'a occurs inside ('b, 'a) S.Step.t
)