SML 中的 Foldl 可以处理字符串列表中的元素并返回另一个列表吗?



如果没有,如果我想使用预定义的函数修改列表中的元素并最终用一行代码返回列表,该怎么办?

例如: 有趣的 upperClass 是预定义的函数字符串 ->字符串,它使字符串中的所有字符都成为 upperclass,这里我有一个列表 ["a","b","c"] 我想以非递归方式编写此函数,并使用折叠器返回 ["Ä","B","C"]。

我之前的尝试是 foldr upperClass(( [] ["a","b","c"],结果证明类型不匹配,因为通常我使用 OP:: 将这些元素放回列表中。

正如你自己评论的那样,你所描述的是map

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

你应该选择map最准确地描述你正在做的事情,因为它可以更快地传达代码的意图。

map做了一些比foldl更具体的事情,因为map只能返回一个与其输入具有相同数量元素的列表,其中每个元素都以完全相同的方式转换并且独立于其他函数(至少在map自愿的范围内(。

事实上,mapfoldr的一个特例,因为您可以使用foldr实现map,但不能反过来:

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方便,但您也可以使用另一个来表达一个。

折叠的想法可以适用于任何树结构,而不仅仅是列表。这是关于如何折叠二叉树的StackOverflow答案,这是关于树尾递归的StackOverflow问答。

让我们看一下foldl的文档,listat http://sml-family.org/Basis/list.html#SIG:LIST.foldl:VAL

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列表。 使用(op ::)foldl也应返回一个列表。

例:

foldl (op ::) [] [1,2,3,4]

返回

val it = [4,3,2,1] : int list

我认为您的挑战是想出一个函数f,该函数在同时处理元素的同时返回字符串列表。(另外,按正确的顺序。

最新更新