【问题标题】:In which functional programming function would one grow a set of items?在哪个函数式编程函数中会增加一组项目?
【发布时间】:2011-03-14 21:47:26
【问题描述】:

这三个中的哪一个(如果有(请提供替代方案))将用于将元素添加到项目列表中?

  • 折叠
  • 地图
  • 过滤器

还有;如何添加项目? (附加到末尾/插入在工作项/其他之后)

【问题讨论】:

  • 一个集合没有结束。集合只是一堆没有顺序的不同值。
  • 什么语言?以上都没有用于增长列表,它们用于折叠、映射函数以及过滤列表的值。
  • 语言不可知,随意使用任何语言作为示例。
  • 这些函数中的每一个都接受一个集合或元素序列,但没有一个用于扩展该集合或序列。折叠产生单个元素。 Map 产生具有相同数量元素的集合或序列。过滤器产生一个大小小于或等于其输入的集合或序列。

标签: functional-programming


【解决方案1】:

函数式编程中的列表通常被定义为递归数据结构,它要么是一个特殊的空值,要么由一个值(称为“头”)和另一个列表(称为“尾”)组成。在 Haskell 中:

-- A* = 1 + A x A*
-- there is a builtin list type:
data [a] = [] | (a : [a])

要在头部添加元素,可以使用“cons”:该函数接受头部和尾部,并生成相应的列表。

-- (:) is "cons" in Haskell
(:) :: a -> [a] -> [a]

x = [1,2,3]   -- this is short for (1:(2:(3:[])))
y = 0 : x     -- y = [0,1,2,3]

要在最后添加元素,您需要向下递归列表以添加它。您可以通过折叠轻松做到这一点。

consAtEnd :: a -> [a] -> [a]
consAtEnd x = foldr [x] (:)
    -- this "rebuilds" the whole list with cons,
    -- but uses [x] in the place of []
    -- effectively adding to the end

要在中间添加元素,需要使用类似的策略:

consAt :: Int -> a -> [a] -> [a]
consAt n x l = consAtEnd (take n l) ++ drop n l
     -- ++ is the concatenation operator: it joins two lists
     -- into one.
     -- take picks the first n elements of a list
     -- drop picks all but the first n elements of a list

请注意,除了头部的插入之外,这些操作会跨越整个列表,这可能会成为性能问题。

【讨论】:

  • 我怀疑我用于列表定义的语法不是正确的 Haskell。如果您知道如何解决,可以编辑或显示给我吗?
【解决方案2】:

“cons”是大多数函数式编程语言中用于构造包括列表在内的各种数据结构的低级操作。在 lispy 语法中,它看起来像这样:

(cons 0 (cons 1 (cons 2 (cons 3 nil))))

视觉上这是一个链表

0 -> 1 -> 2 -> 3 -> nil

或许更准确

cons -- cons -- cons -- cons -- nil
  |       |       |       |
  0       1       2       3

当然,您也可以使用 cons 构造各种类似“树”的数据结构。

树状结构可能看起来像这样

(cons (cons 1 2) (cons 3 4))

即视觉上:

  cons
  /  \
cons cons
/ \   / \
1 2   3 4

不过,大多数函数式编程语言都会提供许多“高级”函数来操作列表。

例如,在 Haskell 中有

  • 追加:(++) :: [a] -> [a] -> [a]
  • 列表理解:[foo c | c
  • 缺点:(:) :: a -> [a] -> [a](正如 Martinho 已经提到的)
  • 还有很多很多more

只是为了提供一个结论性评论,您不会经常以您可能认为的方式对列表中的单个元素进行操作,这是一种命令式思维方式。您更有可能使用递归函数或该行中的某些内容来复制整个结构。编译器/虚拟机负责识别何时可以就地修改内存并更新指针等。

【讨论】:

  • 我不知道“在大多数函数式编程语言中构造各种数据结构,包括列表”部分。除了 LISP,我所知道的所有 FP 语言都只将 cons 用于列表。其他数据结构是用其他机制构建的(即使您仍然可以使用 cons 来构建它们)。哦,等等,LISP 也只对列表使用 cons:在 LISP 中一切都是列表!
  • 确实如此,正如您在 Haskell 中所说,您可能更有可能使用抽象数据类型等更高级别的东西。不过,缺点似乎是最接近通用构造函数的东西。好吧,如果你接受一棵树作为列表的列表,你也可以使用 haskell cons 构造树:[1,2] : [[3, 4]]。
  • 至少,让我这样说吧:根据您的观点,“数据结构”要么是 API,要么是内存布局......
猜你喜欢
  • 2019-06-09
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多