LoginSignup
10
0

【TIPS】Erlang文字列とリストが同じってご存じ?

Last updated at Posted at 2023-12-24

この記事は、Elixir Advent Calendar 2023 シリーズ14 の20日目です


【本コラムは、5分で読め、5分で試せます】

piacere です、ご覧いただいてありがとございます :bow:

下記Erlangモジュール関数を使うと出てくる ~c 文字列って、Elixirのダブルクォート文字列とだいぶ仕様が異なります

今回、それを見分けたり、使い分けるTIPSをまとめておきました

定義

Erlang文字列は、'~' ないしは ~c"~" で定義できます

iex> 'abc'
~c"abc"
iex> ~c"abc"
~c"abc"

実は、~c'~' でも定義できてしまいますw

iex> ~c'abc'
~c"abc"

Elixirのダブルクォート文字列とは別の型

一致しません

iex> 'abc' == "ABC"
false

一致させるには、型変換が必要です

iex> 'abc' == String.to_charlist("abc")
true
iex> List.to_string('abc') == "abc"
true

型チェック

上記 String.to_charlist の関数名通り、Erlang文字列の実体はリストです

iex> "abc" |> is_binary
true
iex> "abc" |> is_list
false
iex> 'abc' |> is_binary
false
iex> 'abc' |> is_list
true

Erlang文字列がリストなのは、実は関数型ならではの理由があり、Haskellなどの他関数型言語も文字列はリストで定義されており、Erlangもその流儀に則っているだけです

これにより、リスト処理と文字列処理を共通化させるジェネリックなプログラミングが可能となります

しかし、リストは効率性に課題を抱えることが多いため、Elixirでは、敢えてリストを止めて、ビットストリングベースの文字列としています

Erlang文字列はリスト処理できる

ということは、Erlang文字列はリスト処理できるということですね

iex> 'abc' |> hd
97
iex>  <<'abc' |> hd>>
"a"
iex> 'abc' |> Enum.split(2)  
{~c"ab", ~c"c"}
iex> Enum.zip('abc', 'xyz')
[{97, 120}, {98, 121}, {99, 122}]
iex> Enum.zip('abc', 'xyz') |> Enum.map(fn {a, b} -> {<<a>>, <<b>>} end)
[{"a", "x"}, {"b", "y"}, {"c", "z"}]

最近のErlang関数事情

以前は、Erlang関数はErlang文字列(つまりリスト)のみ対応していました

iex> 'abc' |> :string.split('b')
[~c"a", ~c"c"]

それが最近は、Elixir文字列(つまりビットストリング)も使えるようになっているし、アレコレ混ぜても動きます

iex> "abc" |> :string.split("b")
["a", "c"]
iex> "abc" |> :string.split('b')
["a", "c"]
iex> 'abc' |> :string.split("b")
[~c"a", ~c"c"]

とは言え、Elixirの String モジュールが充分便利なので、Erlangモジュールを使う機会はあまり無いと思います

10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0