gpt4 book ai didi

sml - 在标准 ml 中定义嵌套函数

转载 作者:行者123 更新时间:2023-12-04 01:58:04 25 4
gpt4 key购买 nike

我是 sml 的新手。我试图将 int 转换为 int 列表。例如,假设有一个输入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

最佳答案

嵌套函数只是将工作负载拆分为多个较小部分的一种方法。另一种选择是非嵌套库函数。主要区别在于,未嵌套的函数不会继承其父级的变量范围,因此它们只能使用自己的输入,而嵌套的函数在其他任何地方都不可用,也不能重复使用。假设您要先解决这个问题:

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-endlet-in- 隐藏它结束:

    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

    请注意函数 mehn 副本隐藏了 digitn 副本。

    为了清楚起见,您还可以用不同的方式命名变量。

  • 或者您可以查看 rev 是如何做它的事情,然后去做。它基本上将其输入视为一个堆栈,并递归地将顶部元素放入新堆栈中,以便顶部成为底部,很像 StackOverflow 的 Logo ,如果它跳出并像 slinky spring 一样倒挂着地。 :

    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 中,这意味着它最终位于底部/末尾。所以我们不需要调用 rev 并保存列表的迭代。

实际上,您不必使用local-in-endlet-in-end 来隐藏辅助函数;虽然在 let-in-end 的情况下继承父函数的作用域可能很有用,但一旦您开始使用带 opaque signatures 的模块,就没有必要隐藏您的函数。 (:> 运算符):

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

由于这是输入到 REPL 中,只有相关函数在模块外可用:

> 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

关于sml - 在标准 ml 中定义嵌套函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49292380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com