创建模块以便在ocaml

时间:2017-04-11 13:02:37

标签: ocaml

我有这样的类型:

type lT = LV of name
        | LC of name
        | LA of lT * lT
        | LAb of name  * lT

我想以一种方式实现一个名为let {s} s的函数,它将以下列方式运行:

let println x = printf "%s\n" (s x)
s (`App(`App(`App(`Bs, `K), `K), `K))  ==>  "B* K K K”

出于这个原因,我已经实现了以下模块:

module type L2C = 
sig
  val c1 : lT -> ([> `T | `L | `J
                        | `A of 'b * 'b | `V of name | `C of name] as 'b)

  val c2 : lT -> ([> `T | `L | `J | `C | `D
                        | `A of 'b * 'b | `V of name | `C of name] as 'b)

  val c3 : lT -> ([> `T | `L | `J | `C | `D | `Sp | `Bp | `Bs | `Cp
                        | `A of 'b * 'b | `V of name | `C of name] as 'b)

  val e : ([< `T | `L | `J | `C | `D | `Sp | `Bp | `Bs | `Cp
                        | `A of 'b * 'b | `V of name | `C of name] as 'b) ->
             ([ `T | `L | `J | `C | `D | `Sp | `Bp | `Bs | `Cp
                        | `A of 'b * 'b | `V of name | `C of name] as 'b)
end

但由于我是ocaml的新手,我无法创建一个“s”函数来获得我想要的输出。

可能有什么方法可以做到这一点?

2 个答案:

答案 0 :(得分:2)

我不太了解您尝试做的事情的详细信息,但我希望这可以提供帮助:

let s expr =
  let rec loop acc = function
    | `Bs -> "B* "^acc
    | `K -> "K "^acc
    | `App(a,b) -> (loop acc a)^(loop acc b)
  in
  loop "" expr

上面的例子非常适用于您提供的示例:

s (`App(`App(`App(`Bs, `K), `K), `K));;

- : string = "B* K K K "

您需要在模式匹配中添加额外的案例,如果您需要有用的类型推断而不是丑陋的多态变体类型,可能需要添加一些类型的注释。

答案 1 :(得分:2)

如果您不必坚持:

s (`App(`App(`App(`Bs, `K), `K), `K))  ==>  "B* K K K”

您可以使用ppx_deriving自动生成将您的类型转换为字符串的函数(以下utop中的示例):

#require "ppx_deriving.std";;
type t = [`App of (t * t) | `B | `K] [@@deriving show];; (* assuming your type is like this *)
> type t = [ `App of t * t | `B | `K ]
> val pp : Format.formatter -> t -> unit = <fun>
> val show : t -> string = <fun> ...
show (`App (`B , `App (`K , `K)));;
- : string = "`App ((`B, `App ((`K, `K))))"