docs: update 29_comprehension.md

This commit is contained in:
Shunsuke Shibayama 2023-09-11 00:49:16 +09:00
parent f8a7413953
commit 482f22374b
2 changed files with 27 additions and 19 deletions

View file

@ -1,27 +1,31 @@
# Comprehension
Array with `[expr | (name <- iterable)+ (predicate)*]`,
set with `{expr | (name <- iterable)+ (predicate)*}`,
You can create a Dict with `{key: value | (name <- iterable)+ (predicate)*}`.
You can create an Array with `[(expr |)? (name <- iterable;)+ (| predicate)?]`,
a set with `{(expr |)? (name <- iterable;)+ (| predicate)?}`,
a Dict with `{(key: value |)? (name <- iterable;)+ (| predicate)?}`.
The first part of the clauses separated by `|` is called the layout clause (location clause), the second part is called the bind clause (binding clause), and the third part is called the guard clause (conditional clause).
A guard clause can be omitted, but a bind clause cannot be omitted, and a guard clause cannot precede a bind clause.
The first part of the clauses separated by `|` is called the layout clause, the second part is called the binding clause, and the third part is called the guard clause.
Either a guard clause or a layout clause can be omitted, but bind clauses cannot be omitted, and a guard clause cannot precede a bind clause.
Comprehension example
```python
# the layout clause is i
# bind clause is i <- [0, 1, 2]
# layout clause: i
# bind clause: i <- [0, 1, 2]
assert [i | i <- [0, 1, 2]] == [0, 1, 2]
# layout clause is i / 2
# bind clause is i <- 0..2
# If you only want to filter, you can omit the layout clause
# This is same as [0, 1, 2].iter().filter(i -> i % 2 == 0).into_array()
assert [i <- [0, 1, 2] | i % 2 == 0] == [0, 2]
# layout clause: i / 2
# bind clause: i <- 0..2
assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0]
# layout clause is (i, j)
# bind clause i <- 0..2, j <- 0..2
# guard clause is (i + j) % 2 == 0
assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
# layout clause: (i, j)
# bind clause: i <- 0..2, j <- 0..2
# guard clause: (i + j) % 2 == 0
assert [(i, j) | i <- 0..2; j <- 0..2 | (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
assert {i % 2 | i <- 0..9} == {0, 1}
assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2}

View file

@ -2,12 +2,12 @@
[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_comprehension.md%26commit_hash%3De959b3e54bfa8cee4929743b0193a129e7525c61)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_comprehension.md&commit_hash=e959b3e54bfa8cee4929743b0193a129e7525c61)
`[expr | (name <- iterable)+ (predicate)*]`で配列、
`{expr | (name <- iterable)+ (predicate)*}`でセット、
`{key: value | (name <- iterable)+ (predicate)*}`でDictが作れます。
`[expr | (name <- iterable)+ | (predicate)*]`で配列、
`{expr | (name <- iterable)+ | (predicate)*}`でセット、
`{key: value | (name <- iterable)+ | (predicate)*}`でDictが作れます。
`|`で区切られた節のうち最初の部分をレイアウト節(配置節)といい、2番目の部分をバインド節(束縛節)、3番目の部分をガード節(条件節)とい
ガード節は省略可能ですがバインド節は省略できず、バインド節より先にガード節を置くことはできません。
`|`で区切られた節のうち最初の部分をレイアウト節(配置節)といい、2番目の部分をバインド節(束縛節)、3番目の部分をガード節(条件節)といいます
ガード節かレイアウト節のどちらかは省略可能ですがバインド節は省略できず、またこれらの順番を入れ替えることはできません。
内包表記の例
@ -16,6 +16,10 @@
# バインド節はi <- [0, 1, 2]
assert [i | i <- [0, 1, 2]] == [0, 1, 2]
# フィルタリングだけしたい場合は、レイアウト節を省略できる
# これは[0, 1, 2].iter().filter(i -> i % 2 == 0).into_array()と同じ
assert [i <- [0, 1, 2] | i % 2 == 0] == [0, 2]
# レイアウト節はi / 2
# バインド節はi <- 0..2
assert [i / 2 | i <- 0..2] == [0.0, 0.5, 1.0]
@ -23,7 +27,7 @@ assert [i / 2 | i <- 0..2] == [0.0, 0.5, 1.0]
# レイアウト節は(i, j)
# バインド節はi <- 0..2, j <- 0..2
# ガード節は(i + j) % 2 == 0
assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
assert [(i, j) | i <- 0..2; j <- 0..2 | (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
assert {i % 2 | i <- 0..9} == {0, 1}
assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2}