如何使我的代码在 SML 中更加模块化?

How can I make my code more modular in SML?

我正在用 SML 编程。我的函数接受一个整数,然后用逗号将它拼接成一个列表。例如数字 12345 -> [1,2.3,4,5]。我的问题是如何使我的代码更加模块化。我有点硬编码我的代码。我希望它适用于无限数量的整数。

fun digits(m:int) =
  if m <10 then
    [m]
  else if m < 100 then
    [m div 10] @ [m mod 10]
  else if m > 100 andalso m < 1000 then
    [(m div 10) div 10] @[(m div 10) mod 10] @ [m mod 10]
  else if m > 1000 andalso m < 10000 then
    [((m div 10) div 10) div 10] @ [((m div 10) div 10) mod 10] @ [(m div 10) mod 10] @ [m mod 10]
  else if m > 10000 andalso m < 100000 then
    [(((m div 10) div 10) div 10) div 10] @ [((m div 10) div 10) div 10 mod 10] @ [((m div 10) div 10) mod 10] @ [(m div 10) mod 10] @ [m mod 10]
  else if m > 100000 andalso m < 1000000 then
    [((((m div 10) div 10) div 10) div 10) div 10] @ [(((((m div 10) div 10) div 10) div 10) mod 10) mod 10] @ [((m div 10) div 10) div 10 mod 10] @ [((m div 10) div 10) mod 10] @ [(m div 10) mod 10] @ [m mod 10]
  else if m > 1000000 andalso m < 10000000 then
    [(((m div 10) div 10) div 10) div 10 div 10 div 10] @ [(((m div 10) div 10) div 10) div 10 div 10 mod 10] @ [((m div 10) div 10) div 10 mod 10]@ [((m div 10) div 10) mod 10] @ [(m div 10) mod 10] @ [m mod 10]                                               
  else
    [(m div 10) div 10] @ [(m div 10) mod 10] @ [m mod 10]

想想你要解决的问题。您无法对所有可能性进行硬编码。

让我们考虑一个基本示例:一位数字。显然,对于任何小于 10 的输入,结果就是列表中的那个数字。

fun digits m =
  if m < 10 then
    [m]

如果大于10,可以是两位数,也可以是更多。我们不知道。但是我们能找到最小的数字吗?

fun smallestDigit m =
  if m < 10 then
    m
  else
    m mod 10

所以如果我们调用 smallestDigit 123 我们会得到 3.

如果我们 123 div 10 我们得到 12。事实证明,如果我们调用 smallestDigit 12,我们会得到 2。我们只需要重复这个直到我们得到所有的数字。在函数式编程中,这种重复通常是通过 递归.

实现的

所以让我们使用递归将它们放在一起。关键是我们有一个停止递归的退出条件,并且其他情况向该退出条件收敛。

fun digits m =
  if m < 10 then
    [m]
  else 
    let
      val smallestDigit = m mod 10
      val remainingDigits = m div 10
    in
      digits remainingDigits @ [smallestDigit]
    end