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
)