实现基本的数组操作。
在函数式语言中,像length、map和reduce这样的数组操作非常常见。
请实现一系列基本的数组操作,不要使用现有的函数。
需要实现的操作的具体数量和名称会因你所在的编程语言轨道而异,以避免与现有名称冲突,但你将要实现的一般操作包括:
append(给定两个数组,把第二个数组中的所有元素添加到第一个数组的末尾);concatenate(给定一系列数组,把所有数组中的所有元素合并成一个扁平数组);filter(给定一个谓词和一个数组,返回所有满足 predicate(item) 为 True 的元素组成的数组);length(给定一个数组,返回其中元素的总数);map(给定一个函数和一个数组,返回对每个元素应用 function(item) 所得结果组成的数组);foldl(给定一个函数、一个数组和一个初始累加器,从左到右把每个元素折叠(归约)进累加器);foldr(给定一个函数、一个数组和一个初始累加器,从右到左把每个元素折叠(归约)进累加器);reverse(给定一个数组,返回一个包含所有原元素、但顺序相反的数组)。注意,传给折叠函数(foldl、foldr)的实参顺序很重要。
在 Roc 中,不使用_任何_内置函数来实现这些数组操作几乎是不可能的,因为你总得有办法向数组追加或前置元素。
在其他语言里,你可能会用 Haskell 的 : 或 Python 的 += 这类运算符,但在 Roc 中,你必须使用 List函数。
所以在本次练习中,你可以使用 List.append(但请避免使用其他任何内置函数)。
许多函数式编程语言把链表作为主要的集合类型。
在链表中,前置一个元素或弹出第一个元素都很高效,所以在那些语言里,你会用 List.prepend 实现数组操作。
不过在 Roc 中,List就是一个数组(一块连续的字节)。
数组的特性与链表不同,比如它可以高效地按下标访问元素,也能高效地追加新元素。
正因如此,在 Roc 中我们经常使用 List.append,很少使用 List.prepend。
Roc 使用的名字和通用指令中列出的略有不同:
concat,而不是 append
join,而不是 concatenate
len,而不是 length
fold,而不是 foldl
fold_rev,而不是 foldr
不过,以下函数名在 Roc 中是标准的:
filtermapreverse试试这样写:
match list {
[] => ...
[first, .. as rest] => ...
}
或者
match list {
[] => ...
[.. as rest, last] => ...
}