あと味

たくさん情報を食べて、たくさん発信すると、あとになって味わい深い。

Perlのリストのおもしろいところ

PerlのリストはPerlらしいというか、結構おもしろいなーと思うことがあります。

Perlのリストの面白いところを紹介してみます。

cons, append

Perlでconsとかappendするいい方法何かなーとか考えてた時に、リストの標準機能でできることに気づきました。

my @one_to_three  = (1, 2, 3);

# cons
my @zero_to_three = (0, @one_to_three);

# append
my @one_to_four = (@one_to_three, 4);

concat

同じような方法でconcat相当もできます。

my @one_to_three  = (1, 2, 3);
my @four_five_six = (4, 5, 6);

# concat
my @one_to_six = (@one_to_three, @four_five_six);

ハッシュ版cons, append, concat

Perlでハッシュを定義する時は、以下のように定義します。

my %foo_bar = (foo => 1, bar => 2);

これはいろんな書籍に書いてあることですが、以下の別記法です。

my %foo_bar = ('foo', 1, 'bar', 2);

ハッシュはkeyとvalueが対になったハッシュをリストコンテキストで評価すれば、ハッシュになるわけですね。

この特徴を利用すれば、ハッシュ版のcons, append, concatも可能になります。

my %foo_bar = (foo => 1, bar => 2);
my %baz_qux = (baz => 3, qux => 4);

# ハッシュ版cons
my %hoge_foo_bar = ('hoge' => 0, %foo_bar);

# ハッシュ版append
my %foo_bar_hoge = (%foo_bar, hoge => 3);

# ハッシュ版concat
my %foo_bar_baz_qux = (%foo_bar, %baz_qux);

面白いですね。

car(head), cdr(tail)

関数型言語でよくあるcar(head), cdr(tail)などもリストの標準の機能でOKです。これくらいのことをするのに、イチイチ関数なんていらんかったんです。

my ($car, @cdr) = (1, 2, 3, 4);

多値っぽいもの

多値っぽいものもできます。

my $zero = 0;
my $one  = 1;
my $two  = 2;

# リストの各要素に10足したリストを返す関数
sub map_add_10 {
  map { $_ + 10 } @_;
}

my ($ten, $eleven, $twelve) = map_add_10($zero, $one, $two);

便利ですね。

分配束縛っぽいもの

引数を分解するのも簡単です。超単純なheadとtailを関数にしてみましょう。(先ほどいらんかったんですって言ったとこですが...)

sub head {
  my ($x, @xs) = @_;
  $x;
}

sub tail {
  my ($x, @xs) = @_;
  @xs;
}

my $head = head(1, 2, 3);
my @tail = tail(1, 2, 3);

補足

面白いんですけど、リストは1次元しか表現できないので、2次元以上はこのワザは使えません。

ちなみに最近まで、同一視していたんですけど、配列とリストはPerlでは別物という扱いだそうです。

参考: リストと配列(Array)はPerlでは別物 - Togetter

まとめ

Perlのリストおもしろいですね。*1

*1:ただ、Perl関数プログラミングするのは、個人的には微妙な感じしてます