Tree 有没有更好的方法来构造这样的优先级队列?

Tree 有没有更好的方法来构造这样的优先级队列?,tree,functional-programming,ocaml,priority-queue,Tree,Functional Programming,Ocaml,Priority Queue,我已经实现了一个优先级队列,它工作得很好。下面是我的类型定义 type 'a t = | Leaf of ('a -> 'a -> int) | Node of 'a * 'a t * 'a t * ('a -> 'a -> int) 我的想法是,树接受一个比较器函数('a->'a->int)并生成一个'a t',它将由比较器排序。 但是,我在每个叶和节点上都有比较器,我想知道是否有更好的方法来实现它。 具体来说,给定一棵树,我希望能够轻松访问它

我已经实现了一个优先级队列,它工作得很好。下面是我的类型定义

type 'a t = | Leaf of ('a -> 'a -> int)
            | Node of 'a * 'a t * 'a t * ('a -> 'a -> int)
我的想法是,树接受一个比较器函数('a->'a->int)并生成一个'a t',它将由比较器排序。
但是,我在每个叶和节点上都有比较器,我想知道是否有更好的方法来实现它。
具体来说,给定一棵树,我希望能够轻松访问它的比较器。我不知道如果我的树的每个节点和叶子上都没有比较器,我是否能做到这一点


谢谢

解决这个问题的标准方法是编写一个给定 包含PQ中包含的类型的模块+比较 您给定的函数返回一个专门用于该类型的新PQ模块 和比较功能

module PriorityQueue (OT : Map.OrderedType) = struct
  type t = 
    | Leaf
    | Node of OT.t * t * t
  (*Define your functions in terms of OT.compare ...*)
end
然后创建一个具体的PriorityQueue模块

module FunnyPQ = PriorityQueue(struct
  type t = int
  let compare _ _ = pred (Random.int 3)
end)
请参阅OrderedType的定义:

当然,你也可以使用你所采取的方法,但要考虑到 将数据类型按以下方式分为两种类型

type 'a pq = 
  | Leaf
  | Node of 'a * 'a pq * 'a pq

type 'a t = { 
  comp : 'a -> 'a -> int ;
  pq : 'a pq
}

请注意,使用这种方法会失去一些类型安全性,因为现在如果您正在编写一个带有签名(例如
'a pq->'a pq->'a pq->'a pq
)的函数,则无法保证第一个pq参数和第二个pq参数是使用相同的比较函数构造的

解决这个问题的标准方法是编写一个给定 包含PQ中包含的类型的模块+比较 您给定的函数返回一个专门用于该类型的新PQ模块 和比较功能

module PriorityQueue (OT : Map.OrderedType) = struct
  type t = 
    | Leaf
    | Node of OT.t * t * t
  (*Define your functions in terms of OT.compare ...*)
end
然后创建一个具体的PriorityQueue模块

module FunnyPQ = PriorityQueue(struct
  type t = int
  let compare _ _ = pred (Random.int 3)
end)
请参阅OrderedType的定义:

当然,你也可以使用你所采取的方法,但要考虑到 将数据类型按以下方式分为两种类型

type 'a pq = 
  | Leaf
  | Node of 'a * 'a pq * 'a pq

type 'a t = { 
  comp : 'a -> 'a -> int ;
  pq : 'a pq
}

请注意,使用这种方法会失去一些类型安全性,因为现在如果您正在编写一个带有签名(例如
'a pq->'a pq->'a pq->'a pq
)的函数,则无法保证第一个pq参数和第二个pq参数是使用相同的比较函数构造的

函子确实可以工作,但我认为comparator函数已经指示了树的类型,因此我不希望创建同时具有类型和函数的函子。我认为您的代码可能有问题。在第二个定义中,您的pq要求首先定义a t,在a t中,pq需要首先定义。我不能用你的方式定义类型。这些定义并不意味着相互依赖。这与他关于使用不同于最初用于构造树的比较器函数的比较器函数的评论是一致的。@nlucaroni:对不起,但我确实希望比较器在一棵树中保持一致。用户提供比较器的唯一方法是构造一个Leaf作为基本情况。@didierc:我不知道添加这样一个独立的结构是否值得。现在编辑的“a t”似乎是一个很好的结构。我会试试。函子确实有效,但我认为comparator函数已经指示了树的类型,因此我不希望创建同时包含类型和函数的函子。我认为您的代码可能有问题。在第二个定义中,您的pq要求首先定义a t,在a t中,pq需要首先定义。我不能用你的方式定义类型。这些定义并不意味着相互依赖。这与他关于使用不同于最初用于构造树的比较器函数的比较器函数的评论是一致的。@nlucaroni:对不起,但我确实希望比较器在一棵树中保持一致。用户提供比较器的唯一方法是构造一个Leaf作为基本情况。@didierc:我不知道添加这样一个独立的结构是否值得。现在编辑的“a t”似乎是一个很好的结构。我试试看。