在模式中重用列表

时间:2011-03-06 14:57:05

标签: list haskell performance pattern-matching reusability

当我写:

sort [x] = [x]

编译器是否足够智能以重用相同的列表,或者我必须明确它?

sort xs@[_] = xs

1 个答案:

答案 0 :(得分:10)

足够聪明吗?我们来看看吧!

ezyang@javelin:~$ cat Foo.hs
module Foo where
foo [x] = [x]

这是STG:

ezyang@javelin:~$ ghc --make Foo.hs -ddump-stg -fforce-recomp
[1 of 1] Compiling Foo              ( Foo.hs, Foo.o )

==================== STG syntax: ====================
Foo.foo =
    \r srt:(0,*bitmap*) [ds_sdP]
        let-no-escape {
          fail_sdO =
              sat-only \r srt:(0,*bitmap*) [ds1_sdN]
                  Control.Exception.Base.patError "Foo.hs:2:0-12|function foo";
        } in 
          case ds_sdP of wild_sdY {
            [] -> fail_sdO GHC.Prim.realWorld#;
            : x_sdV ds1_sdT ->
                case ds1_sdT of wild1_sdZ {
                  [] -> : [x_sdV GHC.Types.[]];
                  : ipv_se0 ipv1_se1 -> fail_sdO GHC.Prim.realWorld#;
                };
          };
SRT(Foo.foo): [Control.Exception.Base.patError]

有趣的是这一行:

                  [] -> : [x_sdV GHC.Types.[]];

我们发现我们正在为x_sdV[]创建一个新的cons-cell。所以不行。但是,这并不算太糟糕,因为x_sdV本身是共享的,所以它只是一个构造函数;此外,我们正在强制列表xs的主干,所以GHC无论如何都需要重写它。所以不要担心。