Stream 获取两个流并将它们合并到OCaml中

Stream 获取两个流并将它们合并到OCaml中,stream,ocaml,record,Stream,Ocaml,Record,我想以递增的顺序取两个整数流,并将它们组合成一个不包含重复项的流,并且应该以递增的顺序。我以以下方式定义了流的功能: type 'a susp = Susp of (unit -> 'a) let force (Susp f) = f() type 'a str = {hd : 'a ; tl : ('a str) susp } let merge s1 s2 = (* must implement *) 第一个函数通过在函数中包装计算来暂停计算,第二个函数计算函数并向我提供计算

我想以递增的顺序取两个整数流,并将它们组合成一个不包含重复项的流,并且应该以递增的顺序。我以以下方式定义了流的功能:

type 'a susp = Susp of (unit -> 'a)
let force (Susp f) = f()

type 'a str =  {hd : 'a ; tl : ('a str) susp }

let merge s1 s2 = (* must implement *)

第一个函数通过在函数中包装计算来暂停计算,第二个函数计算函数并向我提供计算结果

我想模拟如何组合列表的逻辑,即在两个列表上进行匹配,检查哪些元素更大、更小或相等,然后附加(cons)整数,以便对结果列表进行排序

但是,我知道我不能只对流执行此操作,因为我不能像列表一样遍历它,所以我认为我需要逐个整数进行比较,然后暂停计算并继续执行此操作以构建结果流

我有点不知道如何实现这样的逻辑,但是,假设这是我应该如何去做这件事,所以如果有人能给我指出正确的方向,那就太好了


谢谢大家!

如果对输入序列进行排序,则合并列表和序列之间没有太大区别。考虑以下列表上的合并函数:


let rec merge s t =
  match s, t with
  | x :: s , [] | [], x :: s -> x :: s
  | [], [] -> s
  | x :: s', y :: t' ->
    if x < y then
      x :: (merge s' t)
    else if x = y then
      x :: (merge s' t')
    else
       y :: (merge s t')
然后,如果我们将列表上的模式匹配替换为调用
next
,将cons操作替换为调用
cons
,则前面的函数将转换为:

module Merge(Any_seq: seq ) = struct

  open Any_seq

  let rec merge s t =
    match next s, next t with
    | Some(x,s), None | None, Some (x,s) ->
      cons x s
    | None, None -> s
    | Some (x,s'), Some (y,t') ->
      if x < y then
        cons x (merge s' t)
      else if x = y then
        cons x (merge s' t')
      else
        cons y (merge s t')

end
可以用

let test = List_implem.merge [1;5;6] [2;4;9]

然后,为流类型实现相同的函数只需为流编写一个类似的
stream\u core
模块。

您的类型相当于标准库中的非空序列(空序列除外)。另外,您的输入序列本身是否已排序?是的,输入序列也已排序,但忘记指定了。谢谢你的链接!你也可以看看Jane Street的模块,它是类固醇上的Seq,有一个
合并
功能。如果你还想自己实现它以便于学习,我尝试了一下,我可以分享一下。暂且不要说这是家庭作业(另外,虽然它看起来相当正确,但我还没有测试它)。
module List_core = struct
  type 'a t = 'a list
  let cons = List.cons
  let next = function
  | [] -> None
  | a :: q -> Some(a,q)
end
module List_implem = Merge(List_core)
let test = List_implem.merge [1;5;6] [2;4;9]