Functional programming 将优先级队列中的元素移动到较低级别

Functional programming 将优先级队列中的元素移动到较低级别,functional-programming,queue,priority-queue,sml,smlnj,Functional Programming,Queue,Priority Queue,Sml,Smlnj,我有一个多级优先级队列,它被实现为(level:int,priority:int,'a)的列表。数据类型如下所示: datatype 'a queue = NONE | Q of (int * int * 'a) list; 较低级别的元素位于队列的前面。同一级别的元素按优先级排序。我有一个排队功能 因此,如果现有队列是:vala=Q[(3,2,“c”),(3,2,“d”),(5,2,“b”),(5,3,“a”), 然后,将一个15“e”排队 给予 我必须编写一个函数move,它对谓词p进行操

我有一个多级优先级队列,它被实现为(level:int,priority:int,'a)的列表。数据类型如下所示:

datatype 'a queue = NONE | Q of (int * int * 'a) list;
较低级别的元素位于队列的前面。同一级别的元素按优先级排序。我有一个排队功能

因此,如果现有队列是:
vala=Q[(3,2,“c”),(3,2,“d”),(5,2,“b”),(5,3,“a”),
然后,将一个15“e”排队 给予

我必须编写一个函数move,它对谓词p进行操作,将满足谓词p的所有元素移动到q中的较低级别队列。 即:val move:('a->bool)->'a queue->'a queue 下面的定义不起作用

fun move pred (Q((l,p,v)::xs)) =  if (pred (v)) then enqueue (Q xs) (l-1) p v else (move pred (Q xs))
  | move pred (Q[]) = raise Empty

我刚刚开始学习sml。请帮助。

首先,使用名为
NONE
的构造函数是不好的,因为它会覆盖 相同名称的内置选项类型值。第二,你说元素 谓词所满足的应该移到较低的级别-是该级别吗 是否总是比以前的级别低一级

您的
move
将不起作用,因为您显然没有递归调用它 当
pred v
为真时,仅当它不是真时。如果您将
(l,p,v)
排入 递归调用
move pred
的队列(即
move pred(Q xs)
与Q xs)相比,它可能工作得更好

还请注意,此问题非常适合通过折叠解决:

fun move pred (Q elems) =
    let fun enq ((l,p,v), q) = enqueue q (if pred v then l-1 else l) p v
    in foldl enq (Q []) elems end
有趣的移动pred(Q((l,p,v)::xs))=if(pred(v))然后排队(qxs)(l-1)pv否则排队(move pred(qxs))lpv |移动pred(Q[])=上升为空
这也行

谢谢你关于NONE的建议。谢谢你给我指出foldl,并指出我关于递归的错误。这确实很有帮助。实际上,您正在将优先级队列中的每个元素重新添加到一个新的空队列中。折叠版本使这一点更加明显,因为您指定
Q[]
作为基础。我还认为,引发异常的基本情况是不够的,因为所有从列表中移除三元组的递归最终都会到达空列表。您可能想重新思考在一个空队列中移动所有元素意味着什么(这不应该是非法的)。
fun move pred (Q elems) =
    let fun enq ((l,p,v), q) = enqueue q (if pred v then l-1 else l) p v
    in foldl enq (Q []) elems end