Recursion 有没有办法只显示一次?

Recursion 有没有办法只显示一次?,recursion,iteration,sml,converters,radix,Recursion,Iteration,Sml,Converters,Radix,我编写了这个sml函数,它允许我显示Ascii表的前5列 fun radix (n, base) = let val b = size base val digit = fn n => str (String.sub (base, n)) val radix' = fn (true, n) => digit n | (false, n) => radix (n div b,

我编写了这个sml函数,它允许我显示Ascii表的前5列

fun radix (n, base) =
    let
        val b = size base
        val digit = fn n => str (String.sub (base, n))
        val radix' =
            fn (true, n) => digit n
            | (false, n) => radix (n div b, base) ^ digit (n mod b)
    in
        radix' (n < b, n)
    end;

val n = 255;
val charList = List.tabulate(n+1, 
  fn x => print(
      "DEC"^"\t"^"OCT"^"\t"^"HEX"^"\t"^"BIN"^"\t"^"Symbol"^"\n"^
      Int.toString(x)^"\t"^
      radix (x, "01234567")^"\t"^
      radix (x, "0123456789abcdef")^"\t"^
      radix (x, "01")^"\t"^
      Char.toCString(chr(x))^"\t"
  )
);
fun基数(n,基数)=
让
val b=尺寸基准
val digit=fn n=>str(String.sub(base,n))
瓦尔基'=
fn(真,n)=>数字n
|(false,n)=>基数(n div b,base)^位数(n mod b)
在里面
基数(n打印(
“DEC”^\t”^“OCT”^\t”^“HEX”^\t”^“BIN”^\t”^“Symbol”^\n”^
Int.toString(x)^“\t”^
基数(x,“01234567”)^“\t”^
基数(x,“0123456789abcdef”)^“\t”^
基数(x,“01”)^“\t”^
Char.toCString(chr(x))^“\t”
)
);
但是我希望标题:
“DEC”^\t”^“OCT”^\t”^“HEX”^\t”^“BIN”^\t”^“Symbol”
在开始时只显示一次,但我不能这样做。有人知道怎么做吗

另一方面,我希望不使用“基数”函数的复活调用。可能吗?写这个函数是否明智

我希望标题:
“DEC”…
仅在开头显示一次

当前,页眉显示多次,因为它在
列表中被
打印。
制表功能,表中每个数字一次。因此,您可以将打印标题移到该函数之外的父函数中

为了清晰起见,我还可以将单个字符的打印移动到单独的功能中。(我认为您已经很好地缩进了
charList
中的代码,但是如果一个函数做了不止一件事,那么它做的事情就太多了。)

例如

您发现
Char.toCString
比简单地打印任何字符都安全,这非常酷。它似乎给出了一些很好的名称,例如
\t
\n
,但并非每个函数都有。所以,如果你真的想给你的桌子增添趣味,你可以添加一个助手函数

fun prettyName character =
    if Char.isPrint character
    then ...
    else case ord character of
         0 => "NUL (null)"
       | 1 => "SOH (start of heading)"
       | 2 => "STX (start of text)"
       | ...
并使用它而不是
Char.toCString

是否打印字符本身或字符的某些描述可能取决于

我不想使用“基数”函数的复活调用

可能吗

写这个函数是否明智

无论采用哪种方法,您都需要与
基数
函数等价的东西

当然,看起来还可以。你可以把它缩短一点,但是一般的方法是好的

您通过执行
String.sub
常量查找避免了列表递归。太好了

fun prettyName character =
    if Char.isPrint character
    then ...
    else case ord character of
         0 => "NUL (null)"
       | 1 => "SOH (start of heading)"
       | 2 => "STX (start of text)"
       | ...