Повторное использование списков в шаблонах - PullRequest
7 голосов
/ 06 марта 2011

Когда я пишу:

sort [x] = [x]

Достаточно ли умен компилятор, чтобы повторно использовать тот же список, или я должен быть откровенным об этом?

sort xs@[_] = xs

1 Ответ

10 голосов
/ 06 марта 2011

Это достаточно умно? Посмотрим!

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

Вот СТГ:

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.[]];

, где мы видим, что мы создаем новую cons-ячейку для x_sdV и []. Так что нет. Тем не менее, это не так уж плохо, потому что x_sdV сам по себе является общим, так что это всего лишь один конструктор; более того, мы форсируем позвоночник списка xs, поэтому GHC все равно придется его переписать. Так что не беспокойся об этом.

...