11001010(2) = CA(16)
を
1111000011001100(2) = F0CC(16)
に Elixir で展開するための覚書です。
Elixir の内包表記は for
Elixir にも内包表記があります。他の関数型言語とくらべて内包表記っぽくない表記と感じましたが、意味するとろは確かに内包表記です。
iex> for n <- [1,2,3,4,5], do: n * n [1, 4, 9, 16, 25]
iex> for x <- [1,3,5], y <- [2,4,6], do: {x, y} [{1, 2}, {1, 4}, {1, 6}, {3, 2}, {3, 4}, {3, 6}, {5, 2}, {5, 4}, {5, 6}]
ちなみに for/1
はモジュール Kernel.SpecialForms で定義されています。
Elixir (と Erlang)の特徴はバイナリにも内包表記が使える点です。
iex> for <<c <- <<1, 2, 3, 4, 5>> >>, do: c * c [1, 4, 9, 16, 25]
個々の演算の値をバイナリにして、:into
オプションを利用すれば、結果もバイナリで得ることができます。
iex> for <<c <- <<1, 2, 3, 4, 5>> >>, into: <<>>, do: <<c * c>> <<1, 4, 9, 16, 25>>
また個々の演算の値がバイナリになっていればよいので、元のバイナリに対して長さの異なる結果を得ることができます。
iex> for <<c <- <<1, 2, 3, 4, 5>> >>, into: <<>>, do: <<c, c>> <<1, 1, 2, 2, 3, 3, 4, 4, 5, 5>>
加えて任意のサイズのビットで値を取り出すことができます。
iex> for <<bit::1 <- <<128>> >>, into: <<>>, do: <<bit>> <<1, 0, 0, 0, 0, 0, 0, 0>>
バイナリはビット数を指定しない場合は 8 ビットで扱われるため、この <<bit>>
は 8 ビットの値と解釈されます。
もちろんここでもビット数を指定することができるので、例えば次のようにすると元のバイナリが得られます。
iex> for <<bit::1 <- <<128>> >>, into: <<>>, do: <<bit::1>> <<128>>
ビット列を展開する
必要な情報がそろったので、これらを踏まえて。
iex> x = 0xCA 202 iex> <<y::16>> = for <<bit::1 <- <<x::8>> >>, into: <<>>, do: << <<bit::1>>, <<bit::1>> >> <<240, 204>> iex> Integer.to_string(y, 16) "F0CC"
CA(16) から F0CC(16) を得ることができました。
ビット列を文字列に展開する
Elixir の文字列はビット列です。
iex> "" == <<>> true iex> <<65>> == "A" true
つまり文字列に対するいろいろな加工を内包表記を使って書くことができます。
iex> for <<c <- "hello">>, do: Integer.to_string(c, 16) ["68", "65", "6C", "6C", "6F"]
iex> for c <- [0x68, 0x65, 0x6C, 0x6C, 0x6F], into: "", do: <<c>> "hello"
この仕組みを利用すればビット列を任意の文字列に展開することもできます。
iex> for <<bit::1 <- <<0x5A>> >>, into: "", do: if bit == 1, do: "@", else: "_" "_@_@@_@_"
これを踏まえて。 フォントデータをキャラクターで表示してみます。
iex> [0x10, 0x28, 0x44, 0x82, 0xfe, 0x82, 0x82, 0x00] |> Enum.each(&IO.puts(for <<bit::1 <- <<&1>> >>, into: "", do: if bit == 1, do: "[]", else: " ")) [] [] [] [] [] [] [] [][][][][][][] [] [] [] []
キャラクタ以外にも、たとえば 0
→ <<0::24>>
、1
→ <<0xffffff::24>>
と展開すれば 2 値のデータから 24 ビットカラーのデータを作成することができます。
補足:Erlang の内包表記
Erlang にもリストとバイナリ両方の内包表記があります。こちらの方がよく見る内包表記の形式をしています。
- Erlang -- Expressions
> [X * 2 || X <- [1,2,3,4,5]]. [2,4,6,8,10]
> << <<(C* 2)>> || <<C>> <= <<1,2,3,4,5>> >>. <<2,4,6,8,10>>
> [C * 2 || <<C>> <= <<1,2,3,4,5>>]. [2,4,6,8,10]
> << <<(X * 2)>> || X <- [1,2,3,4,5]>>. <<2,4,6,8,10>>
いつか読むはずっと読まない:失われたものを復元するという偉業
とうとう新種として判明し命名されました。
2019年9月現在、全身実物化石と全身復元骨格を間近で見ることができます。これはぜひ見て欲しい。
- 作者: 土屋健,群馬県立自然史博物館,ツク之助
- 出版社/メーカー: イースト・プレス
- 発売日: 2019/05/12
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: 真鍋真
- 出版社/メーカー: CCCメディアハウス
- 発売日: 2019/07/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る