Enjoy Elixir #002 -- 型

# はじめに
- [KFIE](https://kfieyaruki.connpass.com/)という近畿大学産業理工学部の情報系コミュニティがあります
- 最近は、毎週火曜日にLT会をやっているそうです
- 私が学生だったのはもうずいぶん昔のことなのですが、参加させてもらっています
- 毎週、5分間時間をもらって、[Elixir](https://elixir-lang.org/)いいよ！　を伝えていきたいとおもいます
    - [2020/6/9(火)の回](https://kfieyaruki.connpass.com/event/177522/)
- 今日は以下を学びます
    - 型
- A journey of a thousand miles begins with a single step.
- この記事は[Elixir](https://elixir-lang.org/)を触るのがはじめてという方に向けて書いています

----

# もくじ
[001 mix new, iex -S mix, mix format](https://qiita.com/torifukukaiou/items/d04d0273749c41eb50af)
|> [002 型](https://qiita.com/torifukukaiou/items/1f5789dbd05498be1132)
|> [003 Pattern matching](https://qiita.com/torifukukaiou/items/47b088f6c44ccf213226)
|> [004 Modules and functions](https://qiita.com/torifukukaiou/items/2b6f30db0a7d37c4f139)
|> [005 Pipe operator and Enum module](https://qiita.com/torifukukaiou/items/70a350cfc45d0eb58371)
|> [006 HTTP GET!](https://qiita.com/torifukukaiou/items/e4416cca916497ee76fb)
|> [007 Flow](https://qiita.com/torifukukaiou/items/eb1aa2c8842adfc40637)
|> [008 AtCoderを解いてみる](https://qiita.com/torifukukaiou/items/98f875ee4d0f4038b5a2)
|> [999 Where to go next](https://qiita.com/torifukukaiou/items/4fa0747546aafa3fe89a)

----

# 型

- ここからさきは`iex`を起動して確かめることができます

```elixir
iex> 1          # integer
iex> 0x1F       # integer
iex> 1.0        # float
iex> true       # boolean
iex> :atom      # atom / symbol
iex> "elixir"   # string
iex> 'elixir'   # charlist
iex> [1, 2, 3]  # list
iex> [foo: :bar] # keyword list
iex> [{:foo, :bar}] # keyword list
iex> {1, 2, 3}  # tuple
iex> %{name: "torifuku", age: 5} # map
iex> i "elixir"
Term
  "elixir"
Data type
  BitString
Byte size
  6
Description
  This is a string: a UTF-8 encoded binary. It's printed surrounded by
  "double quotes" because all UTF-8 encoded code points in it are printable.
Raw representation
  <<101, 108, 105, 120, 105, 114>>
Reference modules
  String, :binary
Implemented protocols
  Collectable, IEx.Info, Inspect, Jason.Encoder, List.Chars, String.Chars
```

- `i`で"Prints information about the data type of any given term."できます

----

# 四則演算など

```elixir
iex> 1 + 2
3
iex> 10 - 2
8
iex> 5 * 5
25
iex> 10 / 2
5.0
iex> div(10, 2)
5
iex> rem(10, 3)
1
iex> :math.pow(2, 8) # 2の8乗
256.0
iex> 1 == 2
false
iex> 1 == 1.0
true
iex> 1 === 1.0
false
iex> 1 != 2
true
iex> [foo: :bar, hoge: :fuga] == [{:foo, :bar}, {:hoge, :fuga}]
true
iex> 3 > 1
true
iex> "1" > 100
true
iex> 3 < 1
false
iex> 300 >= 2  
true
iex> 300 <= 2
false
iex> false or true
true
iex> 1 || true
1
iex> false || 11
11
iex> true and true
true
iex> nil && 13
nil
iex> true && 17
17
iex> !true
false
iex> round(3.58)
4
iex> trunc(3.58)
3
iex> h round/1
```

- ドキュメントは `h`で表示できます
- 型の異なる大小比較の場合、型の大小が定義されています
    - [Term ordering](https://hexdocs.pm/elixir/operators.html#term-ordering)

```
number < atom < reference < function < port < pid < tuple < map < list < bitstring
```

----

# Strings

```elixir
iex> byte_size("hellö")
6
iex> String.length("hellö")
5
iex> String.upcase("hellö")
"HELLÖ"
iex> h = "hello"
"hello"
iex> w = "world"
"world"
iex> h <> " " <> w
"hello world"
iex> "#{h} #{w}"
"hello world"
```

----

# (Linked) Lists

```elixir
iex> [1, 2, true, 3]
[1, 2, true, 3]
iex> length [1, 2, 3]
3
iex> [1, 2, 3] ++ [4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex> [1, true, 2, false, 3, true] -- [true, false]
[1, 2, 3, true]
iex> list = [1, 2, 3]
iex> hd(list)
1
iex> tl(list)
[2, 3]
```


----

# Tuples

```elixir
iex> tuple_size {:ok, "hello"}
2
iex> elem(tuple, 1)
"hello"
iex> {:ok, content} = File.read("mix.exs")
{:ok,
 "defmodule JsonCsv.MixProject..." }
iex> content
"defmodule JsonCsv.MixProject..."
```

----

# Maps

```elixir
iex> map = %{name: "torifuku", age: 5} 
%{age: 5, name: "torifuku"}
iex> Map.get(map, :name)
"torifuku"
iex> Map.get(map, :height)
nil
iex> new_map = Map.merge(map, %{height: 200})
%{age: 5, height: 200, name: "torifuku"}
iex> map
%{age: 5, name: "torifuku"}
iex> new_map
%{age: 5, height: 200, name: "torifuku"}
iex> map_size(map)
2
iex> map_size(new_map)
3
```

- immutable(Mapだけの話ではなく、全体的に)

> [We say that Elixir data structures are immutable. One advantage of immutability is that it leads to clearer code. You can freely pass the data around with the guarantee no one will mutate it in memory - only transform it.](https://elixir-lang.org/getting-started/basic-types.html#linked-lists)

---

# Anonymous functions

```elixir
iex> add = fn a, b -> a + b end
#Function<43.97283095/2 in :erl_eval.expr/5>
iex> add.(1, 2)
3
iex> (fn a, b -> a + b end).(100, 200)
300
```

----

# Wrapping Up
- 型について学びました
    - integer
    - float
    - boolean
    - atom
    - string
    - charlist
    - list
    - keyword list
    - tuple
    - map
- immutable
- 次回は **Pattern matching** です
- We are the Alchemists, my friends!
    - [Elixir](https://elixir-lang.org/)の使い手のことは、Alchemistと呼ばれます
    - ​Alchemist means that a person who studied alchemy. 
    - Alchemy means that a form of chemistry studied in the Middle Ages that involved trying to discover how to change ordinary metals into gold
    - [アルケミスト 夢を旅した少年](https://www.amazon.co.jp/dp/404275001X)

----

# (おまけ 1)Elixirのlength, size には意味があります
- lengthはデータ構造をトラバースして長さを求める
    - O(n)
    - As a mnemonic, both "length" and "linear" start with "l".
- sizeはデータ構造の中に長さを持っている
    - O(1)
- 参考: [length and size](https://hexdocs.pm/elixir/naming-conventions.html#length-and-size)

----

# (おまけ 2)整数のリストが 'Elixir' のようにシングルクォートで囲まれた文字列で表示されることがあります

```elixir
iex> [69, 108, 105, 120, 105, 114]
'Elixir'
iex> IEx.configure(inspect: [charlists: :as_lists]) 
:ok
iex> [69, 108, 105, 120, 105, 114]
[69, 108, 105, 120, 105, 114]
```

- `:inspect`に指定できるオプションは[Inspect.Opts](https://hexdocs.pm/elixir/Inspect.Opts.html#content)で参照できます
- `IEx.configure/1`自体のヘルプは、`iex`で`h IEx.configure/1`してください

## 参考
- [Charlists](https://hexdocs.pm/elixir/List.html#module-charlists)
- [Elixirで整数リストが「謎の文字」として返ってくる現象と、文字列・文字リストについて](https://qiita.com/im_miolab/items/2d41b10ff005b334295d)

----

# 参考
- [Basic types](https://elixir-lang.org/getting-started/basic-types.html)
- [Basic operators](https://elixir-lang.org/getting-started/basic-operators.html)