问题描述
我搜索并发现有几个人在问这个问题,但我找不到明确的答案。 如何在 sml 中打印非字符串?
例如,如果我有一个 ADT 的实例,即 datatype
声明的类型,并且我想打印该值以进行调试。我是否负责编写一个将此类对象转换为字符串的函数,然后打印该字符串?或者我应该使用一些打印机库吗?或者是否有某种 printObject 或 toString 函数?
另外,如何打印其他非字符串对象,例如 true
和 false
?
看起来 sml 知道如何打印这些对象,因为当我在 emacs 中使用 C-l 编译文件时,我看到如下输出,表明 sml 确实知道如何打印值。
[opening /Users/jimka/Repos/mciml/ex1.1.sml]
type key = string
datatype tree = LEAF | TREE of tree * string * tree
val empty = LEAF : tree
val insert = fn : key * tree -> tree
val member = fn : key * tree -> bool
val t1 = TREE (LEAF,"a",LEAF) : tree
val t2 = TREE (LEAF,TREE (LEAF,"c",LEAF)) : tree
val t3 = TREE (LEAF,TREE (TREE (LEAF,"b",LEAF),LEAF)) : tree
val it = true : bool
val it = () : unit
解决方法
如何在 sml 中打印非字符串?
据我所知,这是不可能的(以可移植的方式)。根据您使用的实现,它可能会公开执行此操作的函数。
另外,如何打印其他非字符串对象,例如 true
和 false
?
许多具有相应基础库结构的类型(例如,int
和 Int
)都具有 toString
函数,因此您可以通过 {{1} 打印布尔 b
} 以及与 print (Bool.toString b)
的相似性,用于 Int.toString
。
一些具体实现的想法:
对于 PolyML,您可以使用函数 int
打印任意类型的值(尽管您可能需要显式类型注释;参数的类型不应有任何类型变量)。
对于 SML/NJ,您可以尝试查看此处讨论的方法 https://sourceforge.net/p/smlnj/mailman/message/21897190/,尽管这似乎比它的价值更麻烦。
对于 MLton,我不知道多态函数之类的东西,但他们有一些关于实现 printf 或类似方法的指南。
看起来Moscow ML 支持函数PolyML.print
,但仅在交互式会话中。我不确定 SML# 对这类事情有什么支持。
我是否负责编写一个函数将这样的对象转换为字符串,然后打印字符串?
一般来说,是的。
看起来 sml 知道如何打印这些对象
根据您的 SML 实现,这是启用的,因为 REPL 可以访问比程序通常可以访问的更多信息。例如,SML/NJ 能够做到这一点,因为 REPL 可以访问其他地方无法获得的类型信息(有关来源,请参阅链接的邮递员线程中的 John Reppy 声明)。
您可能还会发现 MLton 的 TypeIndexedValues 示例页面对这类事情很有帮助,尽管我自己没有仔细检查过它的质量。