如果没有,我想同时使用预定义函数修改列表中的元素并以单行代码结尾返回列表,该怎么办?
例如: fun upperClass是预定义的函数字符串->字符串,使字符串中的所有字符成为上层阶级,这里有一个列表[“ a”,“ b”,“ c”] 我想非递归地使用foldr return [“Ä”,“ B”,“ C”]编写此函数。
我之前的尝试是folder upperClass()[] [“ a”,“ b”,“ c”],结果发现类型不匹配,因为通常我使用OP ::将这些元素放回列表。
答案 0 :(得分:2)
您所描述的就是map
:
val uppercase = String.map Char.toUpper
val uppercaseMany = List.map uppercase
您应该在map
最准确地描述您在做什么时选择它,因为它可以更快地传达代码的意图。
map
的功能比foldl
更具体,因为map
只能返回一个列表,该列表具有与输入相同数量的元素,其中每个元素都已经精确地转换为相同的方式并且独立于其他功能(至少在map
自己同意的范围内)。
实际上,map
是foldr
的特例,因为您可以使用map
来实现foldr
,但不能相反:
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
,但是选择了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:VAL上foldl
的{{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]
,该函数在同时处理元素的同时返回字符串列表。 (而且,顺序正确。)