在纯功能设置中重复使用具有不同区别联合的逻辑

时间:2015-08-20 06:26:06

标签: .net f# functional-programming

我在F#中实现了几棵树:标准BST,红黑树,AVL树,Treaps等。

除了insert / remove操作之外,它们似乎都共享相同的功能集:sizeheightget,{{ 1}},containsfloorceil,blablabla。让我们称它们为“不变树函数”。

尽管这些功能的核心几乎相同,但它们在不同的区分联盟上运作,也就是说,不同的树由不同的区分联盟定义。有没有办法轻松地参数化我的不变树函数,这样每次我实现一种新的树时,我只需要将受歧视的联合与那些不变的实现相结合?

以下是BST的区分联合及其toSeq函数的示例:

get

由于

1 个答案:

答案 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

您可以实现使用活动模式参数化的通用树函数。然后,对于每种树类型,您需要在共享实现的那些函数中实现用于泛型解构的活动模式。