fluorite-7　日本語チュートリアル　Part 12　論理値と比較


[チュートリアルトップ](https://qiita.com/MirrgieRiana/items/a0906c72ebfb46693ab5)

[←前回](https://qiita.com/MirrgieRiana/items/ac24970bc8e2a384ebc0)　[次回→](https://qiita.com/MirrgieRiana/items/cc9e041d8e42c6b0480a)

# レッスン1　論理値

**論理値**とは、`TRUE`（真）と`FALSE`（偽）で表される2個の値のことです。
型名は両方ともBOOLEANです。

```bash:
$ fl7 'TRUE, FALSE'
TRUE
FALSE

$ fl7 'TYPE(TRUE), TYPE(FALSE)'
BOOLEAN
BOOLEAN
```

論理値の数値化は、真は1、偽は0になります。

```bash:
$ fl7 '+TRUE, +FALSE'
1
0
```

# レッスン2　論理値化演算子

前置`?`は**論理値化演算子**です。
付けられた値を論理値に変換します。

----

数値につけた場合、0とNANの場合のみ偽で、そのほかの場合は真を返します。

```bash:
$ fl7 '?0, ?1, ?NAN, ?INFINITY, ?-0.001'
FALSE
TRUE
FALSE
TRUE
TRUE
```

----

文字列に付けた場合、空文字列のみ偽で、そのほかの場合は真を返します。

```bash:
$ fl7 '?"", ?"0", ?"FALSE", ?"false", ?" "'
FALSE
TRUE
TRUE
TRUE
TRUE
```

----

ストリーマに付けた場合、各要素の論理和を得ます。

```bash:
$ fl7 '?(0, 0, 0, 1), ?(0, 0, 0, 0)'
TRUE
FALSE
```

----

配列に付けた場合、空配列の場合は偽で、そのほかは真を返します。
オブジェクトに付けた場合、常に真を返します。
NULLに付けた場合、常に偽を返します。

```bash:
$ fl7 '?[], ?[1], ?[0], ?{}, ?{a: 1}, ?NULL'
FALSE
TRUE
TRUE
TRUE
TRUE
FALSE
```

# レッスン3　否定演算子

前置`!`は**否定演算子**です。
論理値の真偽を反転させます。

```bash:
$ fl7 '!TRUE, !FALSE'
FALSE
TRUE
```

論理値以外の値に付けた場合、論理値化を行った後で真偽を反転します。

```bash:
$ fl7 '!1, !0'
FALSE
TRUE
```

# レッスン4　不等号演算子

中置`>`・`<`・`>=`・`<=`は**不等号演算子**です。

`>`は左辺の方が大きい場合に、`<`は右辺の方が大きい場合に真を返し、そうでない場合に偽を返します。
`=`付きの演算子は、両辺が等しい場合にも真を返します。

```bash:
$ fl7 '[1 > 0, 1 > 1, 1 > 2]'
TRUE,FALSE,FALSE

$ fl7 '[1 < 0, 1 < 1, 1 < 2]'
FALSE,FALSE,TRUE

$ fl7 '[1 >= 0, 1 >= 1, 1 >= 2]'
TRUE,TRUE,FALSE

$ fl7 '[1 <= 0, 1 <= 1, 1 <= 2]'
FALSE,TRUE,TRUE
```

# レッスン5　宇宙船演算子

中置`<=>`は**宇宙船演算子**です。
宇宙船演算子は、左辺が右辺より小さい場合に-1、等しい場合に0、大きい場合に1を返します。

```bash:
$ fl7 '0 <=> 10, 10 <=> 10, 20 <=> 10'
-1
0
1
```

宇宙船演算子は減算演算子の挙動と似ています。

```bash:
$ fl7 '0 - 10, 10 - 10, 20 - 10'
-10
0
10
```

# レッスン6　同値演算子

`===`は**同値演算子**です。
この演算子は、両辺の値が型も含めて完全に等しいか否かを返します。
文字列の内容の判定もこの演算子で判定できます。

`!==`は**否定同値演算子**です。
否定同値演算子は、同値演算子の結果を逆にした値を返します。

```bash
$ fl7 '5 === 5'
TRUE

$ fl7 '"abc" === "abc"'
TRUE

$ fl7 '"1" === 1'
FALSE
```

配列やオブジェクト同士に対する同値演算子は、それが同一の実体か否かを判定します。
配列やオブジェクトの初期化子は必ず新しい実体を生成して返すので、同値演算子は偽になります。
たとえそれが同一の関数内に書かれていようと、初期化子を2度評価すると異なる実体が得られます。
一方、同一の実体を変数に入れた場合、参照の仕方が異なっていても値が同一の実体であれば真となります。

```bash
$ fl7 '[] === []'
FALSE

$ fl7 'f: () -> []; f() === f()'
FALSE

$ fl7 'a: []; b: a; a === b'
TRUE

$ fl7 '{a: 5} === {a: 5}'
FALSE

$ fl7 'f: () -> {a: 5}; f() === f()'
FALSE

$ fl7 'a: {a: 5}; b: a; a === b'
TRUE
```

# レッスン7　等価演算子

`==`は**等価演算子**、`!=`は**否定等価演算子**です。
等価演算子は、「左辺が右辺に相当するか否か」を返します。

同値演算子との違いは、値や値の実体が異なっていても「価値」が同じであれば真になる点です。

----

右辺が数値・文字列・論理値である場合、左辺は一旦数値化・文字列化・論理値化されてから評価されます。

```bash
$ fl7 '"345" == 345'
TRUE

$ fl7 '[] == ""'
TRUE

$ fl7 '{} == TRUE'
TRUE
```

----

同値演算子の両辺を入れ替えた場合には結果が変わることがあります。

```bash
$ fl7 '"1.0" == 1.0'
TRUE

$ fl7 '1.0 == "1.0"'
TRUE
```

これはどうしてこのような結果になるのでしょうか。

`"1.0"`は、数値化すると1です。
数値の1と数値の1.0（すなわち1）は等しいため、真になります。

`1.0`は、数値の1と全く同じ値を表します。
そのため、`1.0`の文字列化は`"1"`です。
文字列の`"1"`と文字列の`"1.0"`は異なるため、偽になります。

----

両辺が配列・オブジェクト同士の場合、更にその要素の一致も再帰的に試みられます。

```bash
$ fl7 '[TRUE, "2"] == [1, 2]'
TRUE

$ fl7 '{b: "2"; a: TRUE} == {a: 1; b: 2}'
TRUE

$ fl7 '[[[5]]] == [[[5]]]'
TRUE
```

# レッスン8　論理演算子

中置`||`は**論理和演算子**です。
両辺のどちらかもしくは両方が真のときに真、それ以外は偽を返します。

```bash
$ fl7 'TRUE || TRUE, TRUE || FALSE, FALSE || FALSE'
TRUE
TRUE
FALSE
```

実は、「左辺が真の場合は左辺を返し、偽の場合は右辺を返す」という挙動をしてます。

```bash
$ fl7 '1 || 5, 0 || 5'
1
5
```

----

中置`&&`は**論理積演算子**です。
両辺が真のときに真、それ以外は偽を返します。
厳密には、「左辺が偽の場合は左辺を返し、真の場合は右辺を返す」という挙動を行います。

```bash
$ fl7 'TRUE && TRUE, TRUE && FALSE, FALSE && FALSE'
TRUE
FALSE
FALSE

$ fl7 '1 && 5, 0 && 5'
5
0
```

# レッスン9　エルビス演算子

中置`?:`は**エルビス演算子**です。
左辺がNULLでない場合は左辺を、NULLの場合は右辺を返します。
エルビス演算子は論理和演算子と似ていますが、左辺に対して真偽判定ではなくNULLチェックを行います。

```bash
$ fl7 '1 ?: 5, 0 ?: 5, NULL ?: 5'
1
0
5
```

エルビス演算子は、NULLか特定の種類の値が入る変数に対してデフォルト値を与える際に強力に働きます。

```bash
$ fl7 'x: 200; x ?: 100'
200

$ fl7 'x: NULL; x ?: 100'
100
```

----

中置`!:`は**逆エルビス演算子**です。
左辺がNULLの場合は左辺を、NULLでない場合は右辺を返します。

```bash
$ fl7 '1 !: 5, 0 !: 5, NULL !: 5'
5
5
NULL
```

逆エルビス演算子は、NULLか特定の種類の値が入る変数に対して参照を行う際に強力に働きます。

```bash
$ fl7 'x: [200]; x !: x[0]'
200

$ fl7 'x: NULL; x !: x[0]'
NULL
```

# レッスン10　三項演算子

**三項演算子**は項を三つとる非常に珍しい演算子です。
「a`?`b`:`c」と記述した時、aが真の場合はbを、偽の場合はcを返します。

```bash
$ fl7 'TRUE ? 1 : 2'
1

$ fl7 'FALSE ? 1 : 2'
2
```

三項演算子は次のように組み合わせて書くことができます。

```perl
f: a, b, c, d -> (
  a
    ? b
      ? 1
      : 2
    : c
      ? 3
      : d
        ? 4
        : 5
);

f(TRUE; TRUE; TRUE; TRUE),
f(TRUE; FALSE; TRUE; TRUE),
f(FALSE; TRUE; TRUE; TRUE),
f(FALSE; TRUE; FALSE; TRUE),
f(FALSE; TRUE; FALSE; FALSE),
```

[オンラインエディタで見る](https://mirrgieriana.github.io/fluorite-7/editor/?s=%0D%0Af%3A%20a%2C%20b%2C%20c%2C%20d%20-%3E%20(%0D%0A%20%20a%0D%0A%20%20%20%20%3F%20b%0D%0A%20%20%20%20%20%20%3F%201%0D%0A%20%20%20%20%20%20%3A%202%0D%0A%20%20%20%20%3A%20c%0D%0A%20%20%20%20%20%20%3F%203%0D%0A%20%20%20%20%20%20%3A%20d%0D%0A%20%20%20%20%20%20%20%20%3F%204%0D%0A%20%20%20%20%20%20%20%20%3A%205%0D%0A)%3B%0D%0A%0D%0Af(TRUE%3B%20TRUE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(TRUE%3B%20FALSE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20FALSE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20FALSE%3B%20FALSE)%2C%0D%0A)

もしくは、次のように括弧を付けて書いてもよいでしょう。

```perl
f: a, b, c, d -> (
  a ? (
    b ? (
      1
    ) : (
      2
    )
  ) : (
    c ? (
      3
    ) : (
      d ? (
        4
      ) : (
        5
      )
    )
  )
);

f(TRUE; TRUE; TRUE; TRUE),
f(TRUE; FALSE; TRUE; TRUE),
f(FALSE; TRUE; TRUE; TRUE),
f(FALSE; TRUE; FALSE; TRUE),
f(FALSE; TRUE; FALSE; FALSE),
```

[オンラインエディタで見る](https://mirrgieriana.github.io/fluorite-7/editor/?s=%0D%0Af%3A%20a%2C%20b%2C%20c%2C%20d%20-%3E%20(%0D%0A%20%20a%20%3F%20(%0D%0A%20%20%20%20b%20%3F%20(%0D%0A%20%20%20%20%20%201%0D%0A%20%20%20%20)%20%3A%20(%0D%0A%20%20%20%20%20%202%0D%0A%20%20%20%20)%0D%0A%20%20)%20%3A%20(%0D%0A%20%20%20%20c%20%3F%20(%0D%0A%20%20%20%20%20%203%0D%0A%20%20%20%20)%20%3A%20(%0D%0A%20%20%20%20%20%20d%20%3F%20(%0D%0A%20%20%20%20%20%20%20%204%0D%0A%20%20%20%20%20%20)%20%3A%20(%0D%0A%20%20%20%20%20%20%20%205%0D%0A%20%20%20%20%20%20)%0D%0A%20%20%20%20)%0D%0A%20%20)%0D%0A)%3B%0D%0A%0D%0Af(TRUE%3B%20TRUE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(TRUE%3B%20FALSE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20TRUE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20FALSE%3B%20TRUE)%2C%0D%0Af(FALSE%3B%20TRUE%3B%20FALSE%3B%20FALSE)%2C%0D%0A)

# まとめ

- `TRUE`（真）と`FALSE`（偽）は論理値。
- 論理値を数値化すると真は1で偽は0。
- 前置`?`で論理値化を行う。
- 前置`!`で否定の論理値化を行う。
- 数値の論理値化は0とNANか否か。
- 文字列の論理値化は空文字列か否か。
- ストリーマの論理値化は各要素の論理和。
- 配列の論理値化は空配列か否か。
- オブジェクトは常に真。
- NULLは常に偽。
- 中置`>` `<` `>=` `<=`で数値の比較ができる。
- 中置`<=>`は左辺と右辺の大小関係を返す。
- `===` `!==`で値が型も含めて完全に一致するかを判定する。
- `==` `!=`で左辺が右辺と等価かを判定する。
- 配列・オブジェクトの等価演算子は再帰的にチェックする。
- 中置`||` `&&`で論理和と論理積。
- 中置`?:`は初期値の設定に使える。
- 中置`!:`はNULLチェックに使える。
- `a?b:c`で`a`が真の場合に`b`、偽の場合に`c`。

# Part 13

[次回→](https://qiita.com/MirrgieRiana/items/cc9e041d8e42c6b0480a)