sml中的foldl是否可以处理字符串列表中的元素并返回另一个列表?

时间:2018-10-02 18:31:19

标签: sml

如果没有,我想同时使用预定义函数修改列表中的元素并以单行代码结尾返回列表,该怎么办?

例如: fun upperClass是预定义的函数字符串->字符串,使字符串中的所有字符成为上层阶级,这里有一个列表[“ a”,“ b”,“ c”] 我想非递归地使用foldr return [“Ä”,“ B”,“ C”]编写此函数。

我之前的尝试是folder upperClass()[] [“ a”,“ b”,“ c”],结果发现类型不匹配,因为通常我使用OP ::将这些元素放回列表。

2 个答案:

答案 0 :(得分:2)

您所描述的就是map

val uppercase = String.map Char.toUpper
val uppercaseMany = List.map uppercase

您应该在map最准确地描述您在做什么时选择它,因为它可以更快地传达代码的意图。

map的功能比foldl更具体,因为map只能返回一个列表,该列表具有与输入相同数量的元素,其中每个元素都已经精确地转换为相同的方式并且独立于其他功能(至少在map自己同意的范围内)。

实际上,mapfoldr的特例,因为您可以使用map来实现foldr,但不能相反:

fun map f = foldr (fn (x, xs) => f x :: xs) []

foldlfoldr可以将事物列表简化为任何事物,例如一棵树:

datatype 'a binaryTree = Leaf | Branch of 'a * 'a binaryTree * 'a binaryTree
fun insert (x, Leaf) = Branch (x, Leaf, Leaf)
  | insert (x, Branch (y, left, right)) =
    if x <= y then Branch (y, insert (x, left), right)
              else Branch (y, left, insert (x, right))
val listToTree = foldl insert Leaf

我方便地选择了foldlfoldr,但是选择了you can also express one using the other

折叠的想法可以在任何树结构上工作,而不仅仅是列表。这是how to fold binary trees上的StackOverflow答案,这是Tail-recursion on trees上的StackOverflow问答。

答案 1 :(得分:1)

我们来看看http://sml-family.org/Basis/list.html#SIG:LIST.foldl:VALfoldl的{​​{1}}的文档

list

如您所见,foldl f init [x1, x2, ..., xn] returns f(xn,...,f(x2, f(x1, init))...) or init if the list is empty. 的最终乘积是函数foldl的乘积。如果返回类型f是列表,则可以返回列表。正如您提到尝试使用f一样,我们知道此运算符包含两个元素,一个类型::元素和一个类型'a的列表,并返回一个类型'a的列表。使用'a的{​​{1}}也应返回一个列表。

示例:

foldl

返回

(op ::)

我认为您面临的挑战是想出一个函数foldl (op ::) [] [1,2,3,4] ,该函数在同时处理元素的同时返回字符串列表。 (而且,顺序正确。)