首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据其现有值向ocaml列表添加值

根据其现有值向ocaml列表添加值
EN

Stack Overflow用户
提问于 2018-02-20 04:52:57
回答 2查看 1K关注 0票数 0

我正在学习地图和折叠函数。我正在尝试编写一个函数,该函数接受一个列表并返回一个列表,其中包含原始值中的所有值,每个值后面都是该值的double。

代码语言:javascript
复制
Example: add_dbls [2;5;8] = [2;4;5;10;8;16]

我尝试的每一件事都会产生一个列表,而不是一个列表。我正努力想出一种更好的方法,使用地图或折叠(或两者兼而有之)。

这是我最初想出来的。我理解为什么这会返回一个列表,但不知道如何修复它。任何想法都将不胜感激!

代码语言:javascript
复制
let add_dbls list = 
    match list with
    | h::t -> map (fun a-> [a;(a*2)]) list
    | [] -> []

另外,我的地图功能:

代码语言:javascript
复制
let rec map f list =
    match list with
    | h::t -> (f h)::(map f t)
    | [] -> []
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-20 05:00:12

应该很简单地看到,List.map总是返回与输入列表相同长度的列表。但你想要一张两倍长的单子。所以List.map不能为你工作。

您可以使用List.fold_leftList.fold_right解决这个问题。如果你在切换到折叠后仍然有困难,你可以用新的信息更新你的问题。

更新

折叠功能(左折叠)的类型如下:

代码语言:javascript
复制
('a -> 'b -> 'a) -> 'a -> 'b list -> 'a

因此,折叠函数接受一个累积的答案和列表中的一个元素,并返回一个新的累积答案。

你折叠的功能如下:

代码语言:javascript
复制
fun a b -> a::b::(b*2)

它尝试使用::运算符向累积列表的末尾添加新元素。但这不是::操作符所做的。它向列表的开头添加一个元素。

没有特别好的方法将元素添加到列表的末尾。这是故意的,因为这是一个缓慢的操作。

当使用左折叠时,您需要协调一致,以反向顺序建立结果,并可能在最后将其逆转。或者您可以使用右折叠(通常不是尾递归)。

票数 1
EN

Stack Overflow用户

发布于 2018-02-20 11:43:13

你就快到了。正如您所观察到的,由于我们得到了列表列表,我们需要将其扁平化以获得最终列表。List.concat函数正是这样做的:

代码语言:javascript
复制
let add_dbls list =
  let l =
    match list with
    | h::t -> List.map (fun a -> [a;(a*2)]) list
    | [] -> []
  in
  List.concat l

下面是计算所需输出的更新函数。现在add_dbls [2;5;8] = [2;4;5;10;8;16]的输出。尽管这样做有效,但它可能并不有效,因为它在原始列表中为每个项目分配了一个新列表。下面是同一个函数的变化,不同的特性取决于l的大小。

代码语言:javascript
复制
(* Safe version - no stack overflow exception. Less efficient(time and size) than add_dbls3 below. *)
let add_dbls2 l =
  List.fold_left
    (fun acc a -> (a*2)::a::acc)
    []
    l
  |> List.rev

(* Fastest but unsafe - stack overflow exception possible if 'l' is large - fold_right is not tail-recursive. *)
let add_dbls3 l =
  List.fold_right
    (fun a acc -> a::(a*2)::acc)
    l
    []
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48878080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档