Sml 在标准ml中定义嵌套函数
我是sml的新手。我试图将int转换为int-list。例如,假设有一个输入1234,那么输出是一个类似于[1,2,3,4]的列表。我的问题是,如何在sml中键入嵌套函数?让我们进去吧?这是我的密码Sml 在标准ml中定义嵌套函数,sml,smlnj,Sml,Smlnj,我是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 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
有趣的数字(a:int):int=
让
乐趣大小(a)=如果a<0,则为零
else x=Int.toString x然后数字s=size(x)
有趣的插入(num,nil)=[num]
|插入(num,xs)=x::插入()
乐趣转换(a,s)=如果s<0则为零
其他插入(a/(10*(s-1)),xs)
然后转换(a-(10*(s-1),s-1)
在里面
结束
或者,如果函数不是相互递归的,则定义需要事先调用的函数。如果函数是相互递归的,则可以查找关键字和
fun F2 ...
fun F3 ...
fun aFunctionCallingF2F3 = <make use of F2 F3 directly>
请注意,您不能这样做
fun areaCircle r = square r * 3.14
fun square x:real = x * x
square
需要在areaCircle之前定义。嵌套函数只是将工作负载分成多个更小部分的一种方法。另一种选择是非嵌套库函数。主要区别在于,非嵌套函数不会继承其父函数的变量范围,因此它们只能使用自己的输入,嵌套的函数在其他任何地方都不可用,无法重复使用。假设您正在尝试解决此问题:
fun digit_meh n = if n < 10 then [n] else n mod 10 :: digit_meh (n div 10)
- 您可以先删除最重要的数字,但计算并不像
那样简单,因为它取决于位数nmod 10
- 您可以生成此列表,然后将其反转:
但是函数fun digit n = rev (digit_meh n)
在该函数之外并不特别有用,因此可以使用local in end或let in end隐藏该函数: 因为结果是在一个额外的参数中累积的,并且digit_meh
应该只接受一个参数,所以用一个额外的累积参数嵌套函数是一个非常有用的技巧 您也可以模仿这种行为:rev
当输入REPL时,只有相关功能在模块外可用: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
> structure Digit : {val digit : int -> int list} signature DIGIT = {val digit : int -> int list} - Digit.digit 1234; > val it = [1, 2, 3, 4] : int list
关于你的第二个问题:是的。你需要输入结束。你指的是如何使用你在“输入结束”中定义的
和insert
等函数吗?是的,我提到了你给出的链接。我在建议5中发现了这一点,但我不明白我应该在“输入”上键入什么,我想可能会遗漏“输入”行并执行数字函数,对吗?你应该尝试使用你之前在中的convert
和'end'之间定义的函数。我写了一些东西。希望这会有帮助。我认为首先集中精力编写正确的非嵌套函数是一个好主意–这些都是胡说八道。我有点喜欢
。它可以让你把重要的函数放在最上面,就像你在Haskell做的那样,顶级函数顺序无关紧要,你有postfix有趣的areaCircle r=square r*3.14square x=x*x
@SimonShine,这太有效了lol。我实际上有时候更喜欢拆分函数。最近,我在一个类型检查项目中编写了长函数我真的很想分割函数…但不能这样做,因为野兽是相互递归的。。。where…
- digit_meh 1234; > val it = [4, 3, 2, 1] : int list
fun digit n = rev (digit_meh n)
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
fun rev L = let fun rev_stack [] result = result | rev_stack (x::xs) result = rev_stack xs (x::result) in rev_stack L [] end
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
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
> structure Digit : {val digit : int -> int list} signature DIGIT = {val digit : int -> int list} - Digit.digit 1234; > val it = [1, 2, 3, 4] : int list