如何使我的代码在 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
我正在用 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