Sml 标准ML扩展列表

Sml 标准ML扩展列表,sml,Sml,方向 函数expand,用于接收任何类型的列表和整数 n,并返回一个列表,其中输入列表的每个项都是 复制n次。例如,expand[1,2,3]3必须为 计算结果为[1,1,1,2,2,2,3,3]。函数的类型必须为“a” 列表→int→‘名单 这里是我的解决方案,我通过使用两个函数来规避一些需求。当我转到列表中的下一项时,我正在努力将n重置为原始值。在我的实现中,我通过将原始的n值保存到s来实现这一点,s永远不会改变。我如何着手消除对s的需求 这里是我的解决方案,我通过使用两个函数来规避一些需求

方向

函数expand,用于接收任何类型的列表和整数 n,并返回一个列表,其中输入列表的每个项都是 复制n次。例如,expand[1,2,3]3必须为 计算结果为[1,1,1,2,2,2,3,3]。函数的类型必须为“a” 列表→int→‘名单

这里是我的解决方案,我通过使用两个函数来规避一些需求。当我转到列表中的下一项时,我正在努力将n重置为原始值。在我的实现中,我通过将原始的n值保存到s来实现这一点,s永远不会改变。我如何着手消除对s的需求

这里是我的解决方案,我通过使用两个函数来规避一些需求

这不是问题。在编写标准ml时,使用helper函数很好。特别是,这里的helper函数是尾部递归,它将优化堆栈框架。有时,模式的嵌套情况是一种替代方法,但由于没有尾部递归,因此需要更多的内存

我如何着手消除对s的需求

我不知道你为什么不喜欢额外的s。但我有一个解决方案:使用闭包隐式保存它

紧凑型:

fun expand [] n =  []
    | expand (node::list) n =
      let   fun n_times f n x = if n = 0 then x else f (n_times f (n-1) x) 
      in    n_times (fn list => case list of node::list => node::[node]) n [node] @ expand list n end
更具可读性的样式:

fun expand [] n =  []
  | expand (node::list) n =
    let
        fun n_times f n x =
            if n = 0
            then x
            else f (n_times f (n-1) x)
    in
        n_times (fn list => case list of node::list => node::[node]) n [node]
        @
        expand list n
    end
这个闭包fn list=>node::list=>node::[node]的案例列表不包括额外的s,但它要做的是帮助n_次来完成n次cons。我想这就是你想要的

顺便说一句,要求扩展了[1,2,3]3和“a列表”→int→‘列表要求您使用curry函数而不是tuple/non-curry函数标准ml中的所有参数都只是一个tuple。因此,我上面给出的解决方案使用curry函数expand[]n和n_乘以fnx。您还可以使用一个帮助函数将非咖喱函数转换为咖喱函数:

fun curry_helper f x y z = f (x, y, z) 
如果有什么地方你不明白,请随时发表评论

这里是我的解决方案,我通过使用两个函数来规避一些需求

这不是问题。在编写标准ml时,使用helper函数很好。特别是,这里的helper函数是尾部递归,它将优化堆栈框架。有时,模式的嵌套情况是一种替代方法,但由于没有尾部递归,因此需要更多的内存

我如何着手消除对s的需求

我不知道你为什么不喜欢额外的s。但我有一个解决方案:使用闭包隐式保存它

紧凑型:

fun expand [] n =  []
    | expand (node::list) n =
      let   fun n_times f n x = if n = 0 then x else f (n_times f (n-1) x) 
      in    n_times (fn list => case list of node::list => node::[node]) n [node] @ expand list n end
更具可读性的样式:

fun expand [] n =  []
  | expand (node::list) n =
    let
        fun n_times f n x =
            if n = 0
            then x
            else f (n_times f (n-1) x)
    in
        n_times (fn list => case list of node::list => node::[node]) n [node]
        @
        expand list n
    end
这个闭包fn list=>node::list=>node::[node]的案例列表不包括额外的s,但它要做的是帮助n_次来完成n次cons。我想这就是你想要的

顺便说一句,要求扩展了[1,2,3]3和“a列表”→int→‘列表要求您使用curry函数而不是tuple/non-curry函数标准ml中的所有参数都只是一个tuple。因此,我上面给出的解决方案使用curry函数expand[]n和n_乘以fnx。您还可以使用一个帮助函数将非咖喱函数转换为咖喱函数:

fun curry_helper f x y z = f (x, y, z) 

如果您不理解,请随时发表评论。

定义帮助函数不是作弊,而是好事。 使用错误的类型定义函数是一个更大的问题-扩展的类型对于练习来说比最终得到的函数的数量更重要。请注意,说明中说明了必须是什么类型,但不允许定义辅助函数

您遇到了问题,因为您试图同时攻击整个输入列表。 当列表问题中的每个元素都有一个do X时,首先要做的是编写一个函数,用一个元素执行X,然后将其list.map

如果我们有一个函数可以重复k次,我们就可以把它应用到每个列表元素上

我们可以将repeat:int*‘a->’写为一个列表,但这需要一个数字和一个东西,并且不方便映射到任何地方。 如果我们能够动态地修正这个数字,并得到一个函数'a->'列表,那就太好了。 如果您以方便的顺序给出参数,则Currying可以让您完全做到这一点

fun repeat 0 i = []
  | repeat n i = i :: repeat (n - 1) i;
负载和测试:

val repeat = fn : int -> 'a -> 'a list
val it = () : unit
- repeat 3 4;
val it = [4,4,4] : int list
到目前为止看起来不错。 我们现在可以编写repeat 4,得到一个函数,它接受某个内容并将其重复四次

让我们使用它:

- fun expand xs n = List.map (repeat n) xs;
val expand = fn : 'a list -> int -> 'a list list
这种类型看起来不太好。让我们看看我们刚刚创建了什么

- expand [1,2,3] 3;
val it = [[1,1,1],[2,2,2],[3,3,3]] : int list list
几乎正确-列表应该是平的

幸运的是,有一个函数可以提供帮助:concat:'a list->'a list,它获取列表列表并将它们附加在一起,因此我们可以将结果传递给它:

- fun expand xs n = List.concat (List.map (repeat n) xs);
val expand = fn : 'a list -> int -> 'a list
看起来好多了

- expand [1,2,3] 3;
val it = [1,1,1,2,2,2,3,3,3] : int list

定义助手函数不是作弊,而是好事。 使用错误的类型定义函数是一个更大的问题-扩展的类型对于练习来说比最终得到的函数的数量更重要。请注意,说明中说明了必须是什么类型,但不允许定义辅助函数

Y 您遇到了问题,因为您试图同时攻击整个输入列表。 当列表问题中的每个元素都有一个do X时,首先要做的是编写一个函数,用一个元素执行X,然后将其list.map

如果我们有一个函数可以重复k次,我们就可以把它应用到每个列表元素上

我们可以将repeat:int*‘a->’写为一个列表,但这需要一个数字和一个东西,并且不方便映射到任何地方。 如果我们能够动态地修正这个数字,并得到一个函数'a->'列表,那就太好了。 如果您以方便的顺序给出参数,则Currying可以让您完全做到这一点

fun repeat 0 i = []
  | repeat n i = i :: repeat (n - 1) i;
负载和测试:

val repeat = fn : int -> 'a -> 'a list
val it = () : unit
- repeat 3 4;
val it = [4,4,4] : int list
到目前为止看起来不错。 我们现在可以编写repeat 4,得到一个函数,它接受某个内容并将其重复四次

让我们使用它:

- fun expand xs n = List.map (repeat n) xs;
val expand = fn : 'a list -> int -> 'a list list
这种类型看起来不太好。让我们看看我们刚刚创建了什么

- expand [1,2,3] 3;
val it = [[1,1,1],[2,2,2],[3,3,3]] : int list list
几乎正确-列表应该是平的

幸运的是,有一个函数可以提供帮助:concat:'a list->'a list,它获取列表列表并将它们附加在一起,因此我们可以将结果传递给它:

- fun expand xs n = List.concat (List.map (repeat n) xs);
val expand = fn : 'a list -> int -> 'a list
看起来好多了

- expand [1,2,3] 3;
val it = [1,1,1,2,2,2,3,3,3] : int list

下面是一个使用标准库函数的解决方案:

fun expand (xs, n) =
    List.concat (List.map (fn x => List.tabulate (n, fn _ => x)) xs)
还有一个:

fun expand (xs, n) =
    List.foldr (fn (x, acc) => List.tabulate (n, fn _ => x) @ acc) [] xs

下面是一个使用标准库函数的解决方案:

fun expand (xs, n) =
    List.concat (List.map (fn x => List.tabulate (n, fn _ => x)) xs)
还有一个:

fun expand (xs, n) =
    List.foldr (fn (x, acc) => List.tabulate (n, fn _ => x) @ acc) [] xs
很高兴认识康卡特。您的高阶函数非常优雅。我很高兴认识康卡特。您的高阶函数非常优雅。我的是相当粗鲁的XD