方向
函数
=INDEX(Sheet1!A:A, MATCH("*"&A2, Sheet1!B:B, 0))
接收任何类型的列表和整数 数字expand
,并返回一个列表,其中输入列表的每一项 复制了n
次。例如,展开[1,2,3] 3必须为 评估为[1,1,1,2,2,2,3,3,3]。函数的类型必须为“ a list→int→‘列表。
这是我的解决方案,其中我通过具有两个功能对要求稍加作弊。当我移至列表中的下一个项目时,我正在努力将n
重置为原始值。在实现过程中,我将原始n
值保存到了n
,但从未更改过。我该如何消除对s
的需求?
s
答案 0 :(得分:3)
定义助手功能不是“欺骗”,这很好。
定义错误类型的函数是一个更大的问题-expand
的类型对练习而言比最终获得的函数数更为重要(请注意,说明中指出“必须是”什么类型) ,但不允许您定义辅助函数)。
您遇到了问题,因为您试图一次“攻击”整个输入列表。
当您遇到“用列表的每个元素执行X运算”的问题时,要做的第一件事就是考虑“编写一个用 one 运算X的函数,然后List.map
进行运算”
如果我们有一个函数可以重复k
次,我们可以将其应用于每个列表元素。
我们可以写repeat: int * 'a -> 'a list
,但这既需要数字又需要东西,并且在任何地方map
都不方便。
如果我们可以动态地“固定”数字并获得函数'a -> 'a list
,那就太好了。
如果您以方便的顺序提供参数,则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
几乎正确-列表应为“扁平”。
幸运的是,List structure具有帮助以下功能的功能:concat: 'a list 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
答案 1 :(得分:1)
这是我的解决方案,其中我通过具有两个功能来对要求稍加作弊。
这不是问题。编写标准ml时,使用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 => case list of node::list => node::[node]
)不包括额外的s
,但要做的是帮助n_times
完成n次弊端。我想这就是你想要的
顺便说一句,要求expand [1,2,3] 3
和‘a list→int→‘a list
要求您使用咖喱函数代替元组/非咖喱函数(标准ml中的所有参数都只是一个元组)。因此,我上面给出的解决方案使用了curry function(expand [] n
和n_times f n x
)。您还可以使用一个帮助函数将非咖喱函数转换为咖喱函数:
fun curry_helper f x y z = f (x, y, z)
如果您不了解某个地方,请随时发表评论。
答案 2 :(得分:1)
以下是使用标准库功能的解决方案:
AmazonS3Config
这是另一个:
fun expand (xs, n) =
List.concat (List.map (fn x => List.tabulate (n, fn _ => x)) xs)