【问题标题】:Practical use of improper lists in Erlang (perhaps all functional languages)Erlang 中不正确列表的实际使用(可能是所有函数式语言)
【发布时间】:2011-07-02 14:15:40
【问题描述】:

我一直在阅读 Erlang 和 OTP 的实际应用,偶然发现了一个关于不正确列表的问题。

不要试图使用列表单元格 这样即使你认为你有 聪明的想法——它容易出错并且 混淆人类和程序 分析工具。也就是说,有 一种或两种有效的创造用途 不正确的列表,但它们被认为是 先进的编程技术和 超出了本书的范围。

超出本书的范围?它必须非常适合 Stackoverflow!
所以我的问题是,当然,一些有效的用途是什么?

【问题讨论】:

  • 以防万一,由于类型系统,您不能在 Haskell 中构造不正确的列表。这没有任何意义。
  • data ListImproper a = Nil | Cons a (ListImproper a) | Improper a a :)
  • 我在看同一本书,来到stackoverflow问同样的问题。

标签: list functional-programming erlang


【解决方案1】:

Erlang 文档建议的一种用法是faking lazy lists

-module(lazy).
-export([ints_from/1]).
ints_from(N) ->
    fun() ->
            [N|ints_from(N+1)]
    end.

【讨论】:

    【解决方案2】:

    Eunit user manual 最底部的关于惰性生成器的部分描述了一种有效的用法。此代码示例应该创建一个非常长的列表,一次将使用一个元素,因此它不是一次生成整个列表,而是创建了一个不正确的列表,其尾部描述了如何生成列表的其余部分:

    lazy_test_() ->
        lazy_gen(10000).
    lazy_gen(N) ->
        {generator,
         fun () ->
             if N > 0 ->
                    [?_test(...)
                     | lazy_gen(N-1)];
                true ->
                    []
             end
         end}.
    

    换句话说,它是一个惰性列表,Erlang 本身并没有给你。

    【讨论】:

    • 这听起来像是一个连续的分数。
    【解决方案3】:

    OTP 标准库字典实现 dict 模块正在为键值对使用不正确的列表。 理由是 2 元组比 2 元素不正确列表使用 1 个字的内存。看 efficiency guide了解详情

    【讨论】:

    • 这是一个私人玩笑,只有查看代码的人才会真正注意到它。节省的费用非常小,并且在宏中定义,因此如果有人真的被它打扰,很容易更改。 :-)
    • 嗯,尽管消息来源证实了这一点,但对我来说,在 R13B04 和 R14B01 中 dict:append(apa, hest, dict:new()) 产生:{dict,1,16,16,8,80,48,{...},{{[],[[apa,hest]],...}}}
    【解决方案4】:

    用于有向图的 OTP 标准 digraph 模块对标记的顶点和边标识符使用了不正确的列表。例如,顶点 42 将被标识为 ['$v'|42],这意味着一对原子(不,不是字符文字!)和一个整数,类似地,边 97 将是 ['$e'|97 ]。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多