我有这样的类型:
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”函数来获得我想要的输出。
可能有什么方法可以做到这一点?
答案 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))))"