我在F#中实现了几棵树:标准BST,红黑树,AVL树,Treaps等。
除了insert
/ remove
操作之外,它们似乎都共享相同的功能集:size
,height
,get
,{{ 1}},contains
,floor
,ceil
,blablabla。让我们称它们为“不变树函数”。
尽管这些功能的核心几乎相同,但它们在不同的区分联盟上运作,也就是说,不同的树由不同的区分联盟定义。有没有办法轻松地参数化我的不变树函数,这样每次我实现一种新的树时,我只需要将受歧视的联合与那些不变的实现相结合?
以下是BST的区分联合及其toSeq
函数的示例:
get
由于
答案 0 :(得分:3)
您可以使用active patterns获得一些帮助:
let get (|Empty|Node|) k t =
let rec get' k = function
| Empty -> None
| Node (k', v, l, r) ->
if k < k' then get' k l
elif k > k' then get' k r
else Some v
get' k t
type T1<'k, 'v> =
| Empty
| Node of 'k * 'v * T1<'k, 'v> * T1<'k, 'v>
let getT1 k t =
let (|Empty|Node|) = function
| Empty -> Empty
| Node (k, v, l, r) -> Node (k, v, l, r)
get (|Empty|Node|) k t
type T2<'k, 'v> =
| Empty2
| Node2 of 'k * 'v * T2<'k, 'v> * T2<'k, 'v>
let getT2 k t =
let (|Empty|Node|) = function
| Empty2 -> Empty
| Node2 (k, v, l, r) -> Node (k, v, l, r)
get (|Empty|Node|) k t
您可以实现使用活动模式参数化的通用树函数。然后,对于每种树类型,您需要在共享实现的那些函数中实现用于泛型解构的活动模式。