将数据类型转换为字符串(SML)

时间:2014-03-03 15:30:09

标签: type-conversion sml

我有一个返回(char * int) list list的函数,如[[(#"D", 3)], [(#"F", 7)]],现在我想知道是否可以将它转换为字符串,以便我可以使用I / O并读取它到另一个文件?

1 个答案:

答案 0 :(得分:3)

首先,我假设你的意思是[[(#"D", 3)], [(#"F", 7)]](注意额外的parens),因为SML需要围绕元组构造的括号。 OCaml使用稍微不同的语法,并允许使用逗号(如a, b)来构造元组。我提到这一点是因为以下内容完全针对标准ML,并不适用于OCaml,因为我相信在OCaml中你最好的选择是一种完全不同的方法,我不太了解它(宏,即ocamlp4 / 5)。所以我认为这只是一个错字,你对Standard ML感兴趣。

现在,遗憾的是标准ML中没有通用toString功能。这样的东西必须在语言和实现方面有一些特殊的支持,因为不可能编写类型为'a -> string的函数。您基本上必须为每种类型toString : t -> string编写自己的t

你可以想象,这很快就会变得乏味。我花了一点时间研究选项(对于这个和其他样板函数,如compare : 't * 't -> order),并且在“工作ML'er的泛型”一文中概述了一种非常有趣的技术(http://dl.acm.org/citation.cfm?id=1292547 )但它非常先进,我实际上永远无法获得编译代码(这篇文章非常有趣)。该论文中描述的完整泛型库位于MLton lib repo(https://github.com/MLton/mltonlib/tree/master/com/ssh/generic/unstable)中。也许你会有更好的运气?

这是一个稍微轻一点的重量方法,功能不强,但更容易理解,恕我直言。我在阅读了那篇论文之后写了这篇文章并努力让它发挥作用。我们的想法是为toString函数编写构建块(在本例中称为show),并将它们与您自己类型的其他函数组合在一起。

structure Show =
   struct
      (* Show.t is the type of toString functions *)
      type 'a t = 'a -> string

      val int: int t = Int.toString

      val char: char t = Char.toString

      val list: 'a t -> 'a list t =
       fn show => fn xs => "[" ^ concat (ExtList.interleave (map show xs) ",") ^ "]"

      val pair: 'a t * 'b t -> ('a * 'b) t =
       fn (showa,showb) => fn (a,b) => "(" ^ showa a ^ "," ^ showb b ^ ")"

      (* ... *)
   end

由于您的类型实际上没有任何用户定义的数据类型,因此使用此结构编写toString函数非常容易:

local
   open Show
in
   val show : (char * int) list list -> string = list (list (pair (char, int)))
end

- show [[(#"D", 3)], [(#"F", 7)]] ;
val it = "[[(D,3)],[(F,7)]]" : string

我喜欢这个是组合的函数读取类似于内部翻转的类型。这是一种非常优雅的风格,当我从上面链接的仿制药文件中看到它时,我无法理解它。

Show的其余代码(以及用于相等性比较的相关模块Eq)位于:https://github.com/spacemanaki/lib.sml