Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 什么时候在F#中使用序列而不是列表?_List_F# - Fatal编程技术网

List 什么时候在F#中使用序列而不是列表?

List 什么时候在F#中使用序列而不是列表?,list,f#,List,F#,我知道a实际上包含值,a是IEnumerable的别名。在实际的F#开发中,什么时候应该使用序列而不是列表 以下是我可以看到的一些原因,当序列更好时: 与其他.NET语言或库交互时,需要 IEnumerable 需要表示一个无限序列(在实践中可能不是很有用) 需要惰性评估 还有其他的吗?我认为你关于什么时候选择Seq的总结非常好。以下是一些补充要点: 在编写函数时,默认情况下使用Seq,因为这样它们就可以处理任何.NET集合 如果需要高级功能,如Seq.windowed或Seq.pairw

我知道a实际上包含值,a是
IEnumerable
的别名。在实际的F#开发中,什么时候应该使用序列而不是列表

以下是我可以看到的一些原因,当序列更好时:

  • 与其他.NET语言或库交互时,需要
    IEnumerable
  • 需要表示一个无限序列(在实践中可能不是很有用)
  • 需要惰性评估

还有其他的吗?

我认为你关于什么时候选择
Seq
的总结非常好。以下是一些补充要点:

  • 在编写函数时,默认情况下使用
    Seq
    ,因为这样它们就可以处理任何.NET集合
  • 如果需要高级功能,如
    Seq.windowed
    Seq.pairwise
我认为默认情况下选择
Seq
是最好的选择,那么我什么时候会选择不同的类型呢

  • 当需要使用
    head::tail
    模式进行递归处理时,请使用
    List
    (实现一些标准库中不可用的功能)

  • 当您需要一个可以逐步构建的简单不可变数据结构时,请使用
    List
    (例如,如果您需要在一个线程上处理列表-以显示一些统计信息-并在收到更多值(即来自网络服务)时在另一个线程上同时继续构建列表)

  • 使用短列表时使用
    List
    ——如果值通常表示空列表,则List是最好的数据结构,因为在这种情况下它非常有效

  • 需要大量值类型集合时,请使用
    Array

    (阵列将数据存储在平面内存块中,因此在这种情况下,它们的内存效率更高)

  • 当您需要随机访问或更高的性能(和缓存位置)时,请使用
    Array


    • 只有一个小问题:
      Seq
      Array
      在并行性方面优于
      List


      您有几个选项:从F#PowerPack、模块和(异步计算)。列表由于其顺序性(
      head::tail
      composition),对于并行执行来说非常糟糕。

      在以下情况下也更喜欢
      seq

      • 您不希望同时在内存中保存所有元素

      • 表现并不重要

      • 您需要在枚举之前和之后执行一些操作,例如连接到数据库并关闭连接

      • 您没有连接(重复的
        Seq.append
        将导致堆栈溢出)

      在以下情况下首选
      列表

      • 没有多少要素

      • 你会做很多准备和斩首


      seq
      list
      都不利于并行性,但这并不一定意味着它们也不好。例如,您可以使用其中一个来表示要并行完成的一小部分独立工作项。

      您应该始终在公共API中公开
      Seq
      。在内部实现中使用
      列表
      数组

      列表功能更强大,数学更友好。当每个元素相等时,两个列表相等

      顺序不是

      let list1 =  [1..3]
      let list2 =  [1..3]
      printfn "equal lists? %b" (list1=list2)
      
      let seq1 = seq {1..3}
      let seq2 = seq {1..3}
      printfn "equal seqs? %b" (seq1=seq2)
      

      非常感谢-正是我想要的。在学习F#以了解为什么有这两个元素(list&seq)为您提供了类似的功能时,您会感到困惑。“当您需要一个简单的不可变数据结构时,可以使用
      list
      […],该结构可以逐步构建[…],同时在另一个线程上继续构建列表[…]”你能在这里详细解释一下你的意思吗?谢谢。@Noein的想法是,您可以始终迭代列表(它们是不可变的),但您可以使用
      x::xs
      创建新列表,而不中断任何正在迭代
      xs
      的现有工作进程。这是一个很好的观点-我想到的场景是当您需要在一个线程上构建集合时(即,当您从某个服务接收到值时)并从另一个线程使用它(即,计算统计数据并显示它)。我同意并行处理(当您的内存中已经有所有数据时),拥有
      Array
      PSeq
      要好得多。为什么你说
      seq
      list
      在并行性方面更好?
      seq
      由于其顺序性,对并行执行也很糟糕……我发现无限序列非常有用和常见。System.Random.Next()已经是一个“无限序列”例如,伪装。通常我想要生成尽可能多的元素。我最近用F#编写了一个俄罗斯方块,并将方块生成表示为一个无限序列:它将根据游戏进行的需要创建尽可能多的块。@U Asik博士注意到,以这种方式生成的
      seq
      每次y都会生成不同的随机数你看,这显然是非确定性错误的来源……”“seq和list都不利于并行性”:你能详细解释一下为什么seq对并行性不好吗?那么,什么对并行性有好处呢,只有数组?@Dr_Asik数组是最好的,因为你可以递归地细分它们,并保留良好的引用位置。树是次好的,因为你也可以细分它们,但引用位置不太好。列表和序列是不好的,因为你可以不能细分它们。如果你划分出替代元素,那么你会得到最差的引用位置。Guy Steele讨论了妨碍并行性的线性集合,尽管他只考虑工作和深度,而不考虑位置(又称缓存复杂性).这是因为它们与其他.NET语言配合得很好吗?也就是说,因为
      Seq
      被视为
      IEnumerable
      ?不是因为良好的设计实践。Expo