漂亮的打印表达递归

时间:2018-04-26 19:19:31

标签: sml

infix v;
infix &;
datatype s = P | Q | S
         | ~ of s
         | v of s * s
         | & of s * s;

我创建了一个函数(s - >单位)来将类型s打印为字符串

fun printS(P) = print "P"
  | printS(Q) = print "Q"
  | printS(P & Q) = print "P & Q";

我的问题是,如果我有更复杂的问题,我怎么能递归打印? P v~Q& P.

1 个答案:

答案 0 :(得分:3)

您可以通过将子树作为变量进行模式匹配来递归地打印表达式,然后引用这些子树。在您的示例中,您只匹配P & Q,它只是一棵树。

fun printS P = print "P"
  | printS Q = print "Q"
  | printS S = print "S"
  | printS (p & q) = (print or printS ...; print or printS ...; ...)

不是指实际的PQ,而是变量pq,这些可以是任何子表达式。由于您的函数返回 unit ,因此您需要多次打印。除此之外,您可能希望打印的某些内容是递归数据类型,因此您可以使用专门的printS代替。

我可能会将其转换为字符串并打印一次字符串:

fun toString P = "P"
  | toString Q = "Q"
  | toString S = "S"
  | toString (p & q) = "(" ^ toString p ^ " & " ^ toString q ^ ")"
  | toString ... = ...

然后打印出来:

fun printS s = print (toString s)

真正的挑战在于打印最少量的括号:

printS ((P v Q) & (Q v P))

最好不要打印P v Q & Q v P,因为它们不是相同的表达方式。