如果没有,如果我想使用预定义的函数修改列表中的元素并最终用一行代码返回列表,该怎么办?
例如: 有趣的 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
自愿的范围内(。
事实上,map
是foldr
的一个特例,因为您可以使用foldr
实现map
,但不能反过来:
fun map f = foldr (fn (x, xs) => f x :: xs) []
foldl
和foldr
可以将事物列表简化为任何内容,例如一棵树:
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
我选择了foldl
和foldr
方便,但您也可以使用另一个来表达一个。
折叠的想法可以适用于任何树结构,而不仅仅是列表。这是关于如何折叠二叉树的StackOverflow答案,这是关于树尾递归的StackOverflow问答。
让我们看一下foldl
的文档,list
at 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
,该函数在同时处理元素的同时返回字符串列表。(另外,按正确的顺序。