2017-04-11 66 views
1

嵌套函數創建一個模塊,我有這樣的類型:爲了打印OCaml中

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

我想實現一個名爲讓我們說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」函數來獲得我想要的輸出。

什麼可能是一種可能的方式來做到這一點?

+0

我想@ RichouHunter的答案是你正在尋找的。只是想指出,有[print_endline](https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALprint_endline) –

回答

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 " 

如果您需要有用的類型推斷,而不是醜陋的多態變體類型,則需要爲模式匹配添加額外的案例,也可能需要添加幾個類型的註釋。

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))))"