我是sml的新人。我试图将int转换为int list。例如,假设存在输入1234,则输出是类似[1,2,3,4]的列表。我的问题是,如何在sml中键入嵌套函数?让我们结束?有我的代码。
fun digit (a : int): int =
let
fun size (a) = if a < 0 then nil
else x = Int.toString x then digit s = size(x)
fun insert (num, nil) = [num]
| insert (num,xs) = x :: insert ()
fun convert (a, s) = if s < 0 then nil
else insert (a / (10*(s - 1)), xs)
then convert(a - (10*(s - 1), s - 1)
in
end
答案 0 :(得分:2)
fun areaCirle r:real =
let fun square x:real = x*x
val pi = 3.14
in
pi * square r
end
例如,
and
或者,如果它们不是相互递归的,则预先定义需要事先调用的函数。如果它们是相互递归的,您可以查找关键字fun F2 ...
fun F3 ...
fun aFunctionCallingF2F3 = <make use of F2 F3 directly>
。
fun square x:real = x * x
fun areaCircle r = square r * 3.14
例如,
fun areaCircle r = square r * 3.14
fun square x:real = x * x
请注意,您无法执行
square
需要在areaCircle之前定义 UInt32
。
答案 1 :(得分:1)
嵌套函数只是将工作负载分成多个较小部分的一种方法。另一种选择是非嵌套库函数。主要区别在于没有嵌套的函数不会继承其父变量范围,因此它们只能使用自己的输入,并且嵌套的函数不能在任何地方使用别的,不能重复使用。让我们说你是第一次尝试这个问题:
fun digit_meh n = if n < 10 then [n] else n mod 10 :: digit_meh (n div 10)
你意识到它并没有完全符合你的要求:
- digit_meh 1234;
> val it = [4, 3, 2, 1] : int list
您可以先移除最重要的数字,但计算并不像n mod 10
那么简单,因为它取决于数字位数。
您可以生成此列表,然后将其反转:
fun digit n = rev (digit_meh n)
但是函数digit_meh
在此函数之外并不是特别有用,因此可以使用 local-in-end 或 let-in-end隐藏它:
local
fun digit_meh n = if n < 10 then [n] else n mod 10 :: digit_meh (n div 10)
in
val digit = rev o digit_meh
end
fun digit n =
let fun meh n = if n < 10 then [n] else n mod 10 :: meh (n div 10)
in rev (meh n) end
请注意功能meh
的{{1}}影子n
digit
副本的副本。
为清楚起见,您还可以区别对变量命名。
或者你可以看看n
如何做它的事情并做到这一点。它基本上将其输入视为一个堆栈,并将顶部元素递归地放入一个新的堆栈中,以便顶部成为底部,就像StackOverflow的徽标看起来像是跳出来并倒置像{{3 }}:
rev
因为结果是在一个额外的参数中累积的,并且fun rev L =
let fun rev_stack [] result = result
| rev_stack (x::xs) result = rev_stack xs (x::result)
in rev_stack L [] end
应该只接受一个参数,所以使用额外的累积参数嵌套一个函数是一个非常有用的技巧。
你也可以模仿这种行为:
rev
这样,我们首先继续处理最不重要的数字,但我们将它放在堆栈fun digit N =
let fun digit_stack n result =
if n < 10
then n::result
else digit_stack (n div 10) (n mod 10::result)
in f N [] end
中,这意味着它最终位于底部/末尾。因此,我们不需要调用result
并保存列表的迭代。
在实践中,您不必使用 local-in-end 或 let-in-end 隐藏辅助功能;虽然在 let-in-end 的情况下继承父函数的范围很有用,但是一旦开始使用{{3}的模块,就没有必要隐藏你的函数。 (rev
运算符):
:>
将其输入REPL时,只有相关功能可在模块外部使用:
signature DIGIT =
sig
val digit : int -> int list
end
structure Digit :> DIGIT =
struct
fun digit_stack n result =
if n < 10
then n::result
else digit_stack (n div 10) (n mod 10::result)
fun digit n = digit_stack n []
end