Erlang(或许所有函数式编程语言)中不当列表的实际应用

10

我一直在阅读《Erlang和OTP实战》,并遇到了一个与不恰当列表有关的问题。

即使您认为自己有聪明的想法,也不要试图以这种方式使用列表单元 - 它容易出错,并且会混淆人类和程序分析工具。话虽如此,有一两个有效的用途可以创建不恰当的列表,但它们被视为高级编程技术,并超出了本书的范围。

超出本书的范围?这一定非常适合在Stackoverflow上讨论!
那么我的问题是,当然,有哪些有效的用途呢?


仅供参考,由于类型系统的限制,您无法在Haskell中构造不当的列表。这是没有意义的。 - YasirA
数据类型 ListImproper a = Nil | Cons a (ListImproper a) | Improper a a - I GIVE CRAP ANSWERS
我正在阅读同一本书,然后来到stackoverflow问同样的问题。 - yilmazhuseyin
4个回答

8

Erlang文档建议的一个用法是模拟惰性列表

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

5

Eunit用户手册的最底部,有一个关于延迟生成器的章节,描述了一种有效的用法。这个代码示例旨在创建一个非常长的列表,每次只消耗一个元素,因此它创建了一个不正确的列表,其尾部描述了如何生成其余的列表,而不是一次性生成整个列表:

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

换句话说,它是一个懒列表,这是Erlang本身无法提供的。

1
这听起来像是一个连分数。 - CMCDragonkai

4

OTP标准库字典实现中的dict模块使用了不当的列表作为键值对。 这样设计的理由是2元组比2个元素的不当列表多使用1个单词的内存。详情请参阅 效率指南


8
这只是一种私人玩笑,只有那些查看代码的人才会注意到它。这样做可以稍微节省一点资源,并且它被定义为一个宏,所以如果真正有人因此感到不安,很容易进行更改。 :-) - rvirding
嗯,尽管源代码确认了这一点,在我使用的 R13B04 和 R14B01 版本中 dict:append(apa, hest, dict:new()) 返回的结果是: {dict,1,16,16,8,80,48,{...},{{[],[[apa,hest]],...}}} - Adam Lindberg

1

OTP标准digraph有向图模块在标记顶点和边缘标识符时使用不当的列表。例如,顶点42将被标识为['$v'|42],其中包含一个原子和一个整数(不是字符字面量!),类似地,边缘97将被标识为['$e'|97]。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接