简体   繁体   English

BST使用模块-OCaml

[英]BST using modules - OCaml

I am trying to create module/interface (i dont exactly know how its called, i am new to the language) for basic operations on BST in OCaml. 我正在尝试为OCaml中的BST上的基本操作创建模块/接口(我不完全知道它的调用方式,我是该语言的新手)。 My goal is to have an implementation that lets me doing something like this: 我的目标是拥有一个可以让我做这样的事情的实现:

T.create();;
T.push(2);;
T.push(3);;
T.push(5);;

in order to get a bst tree consisting of 2,3,5. 为了得到由2,3,5组成的bst树。

But at the moment to achieve this i have to write something like this: 但是目前要实现这一点,我必须编写如下内容:

 let teeBst = T.push(2)(T.push(3)(T.push(5)(T.create())));;

So when I am checking/using my code I have to do it like this: 因此,当我检查/使用我的代码时,我必须这样做:

    let tee2 = T.push(2)(T.push(3)(T.push(5)(T.create())));;
    T.postorder(tee2);;

The output is fine: 输出很好:

 # val tee2 : T.bt = <abstr>
 # - : int list = [2; 3; 5]

But, as I said before, I would like to achieve this doing as below: 但是,正如我之前所说,我希望做到这一点,如下所示:

T.push(2);;
T.push(3);;
T.push(5);;
T.postorder();;

(I realise this requires some changes to my postorder function but the one I am currently using is a temporary one so I can check the tree I have atm ) (我意识到这需要对我的postorder函数进行一些更改,但是我当前正在使用的是临时的,因此我可以检查我拥有atm的树)

Below is my implementation. 下面是我的实现。 If you see the solution, please let me know ;) 如果您看到解决方案,请让我知道;)

   module type Tree =
    sig
        type bt
        val create: unit -> bt
        val push: int -> bt -> bt
        val find: int -> bt -> bool
        val preorder: bt -> int list
        val postorder: bt -> int list
        val inorder: bt -> int list
    end;;

module T : Tree =
    struct
        type bt = E | B of bt * int * bt
        let create () = E
        let rec push x = function
            | E -> B(E, x, E)
            | B (l, y, r) when x<y -> B(push x l, y, r)
            | B (l, y, r) when x>y -> B(l, y, push x r)
            | xs -> xs;;

        let rec find x = function
            | E -> false
            | B(l, y,_) when x< y -> find x l
            | B(_,y,r) when x>y -> find x r
            | _ -> true;;

        let rec preorder = function
            | B(l,v,r) -> v::(preorder r) @ (preorder l)
            | E -> [];;

        let rec inorder = function
            | B(l,v,r) ->(inorder r) @ v::(inorder l)
            | E -> []


        let rec postorder = function
            | B(l,v,r) -> (postorder r) @ (postorder l) @ [v]
            | E -> []
    end;;

It seems like you want modules to be classes, but I'd advise you to consider more idiomatic solutions. 似乎您希望模块成为类,但我建议您考虑使用更多惯用的解决方案。 Have you considered using the pipe operator? 您是否考虑过使用管道操作器?

T.create()
|> T.push(2)
|> T.push(3)
|> T.push(5)
|> T.postorder;;

Or with local open (which makes more sense if you have a module with a longer name than just T of course) you can even do 或者使用本地开放(如果您的模块名称比T更长,那当然更有意义),您甚至可以

T.(
  create()
  |> push(2)
  |> push(3)
  |> push(5)
  |> postorder
);

What you're asking for would require introducing global mutable state, which isn't just "some changes" but an entirely different paradigm. 您要求的是引入全局可变状态,这不仅是“一些更改”,而且是一种完全不同的范例。 And one that is generally frowned upon because it makes your code unpredictable and hard to debug since it relies on state that might change at any moment from anywhere. 人们通常对此不屑一顾,因为它依赖于随时可能随时随地变化的状态,从而使您的代码不可预测且难以调试。

Another possibility is to actually use classes, since OCaml has those too. 另一种可能性是实际使用类,因为OCaml也有那些类。 Then you'd still have mutable state, but it would at least be contained. 这样您仍然会具有可变状态,但是至少会被包含在内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM