```{eval-rst}
:tocdepth: 2
```
```{contents}
---
local:
depth: 2
---
```
このドキュメントは、[Coconut プログラミング言語](http://evhub.github.io/coconut/) のすべての機能をカバーしており、チュートリアルによる紹介ではなく、リファレンス/仕様として意図されています。Coconut の紹介とチュートリアルについては、[チュートリアル](./HELP.md) を参照してください。
Coconut は、**シンプルでエレガントな Python 関数型プログラミング** 用に構築された [Python](https://www.python.org/) のバリアントです。Coconut 構文は、最新の Python 3 構文の厳密なスーパーセットです。したがって、Python に精通しているユーザーは、Coconut のほとんどをすでに使い慣れているでしょう。
Coconut コンパイラは、Coconut コードを Python コードに変換します。Coconut コンパイラにアクセスする主な方法は、リアルタイム コンパイル用のインタープリターも備えた Coconut コマンドライン ユーティリティを使用することです。コマンドライン ユーティリティに加えて、Coconut は IPython/Jupyter ノートブックの使用もサポートしています。
Coconut の構文は主に Python に基づいていますが、Coconut に影響を与えた他の言語には [Haskell](https://www.haskell.org/)、[CoffeeScript](http://coffeescript.org/)、[F
ブラウザで Coconut を試してみたい場合は、[オンライン インタープリター](https://cs121-team-panda.github.io/coconut-interpreter) を確認してください。ただし、古いバージョンの Coconut が実行されている可能性があることに注意してください。
```{contents}
---
local:
depth: 2
---
```
Coconut は [Python パッケージ インデックス](https://pypi.python.org/pypi/coconut) でホストされているため、以下を使用して簡単にインストールできます。
`pip`
. [Pythonをインストール](https://www.python.org/downloads/)し、コマンドラインプロンプトを開いて、次のように入力します。
```
pip install coconut
```
これにより、Coconut とその必要な依存関係がインストールされます。
_注: 古いバージョンの Coconut がインストールされていて、アップグレードしたい場合は、以下を実行します。
`pip install --upgrade coconut`
代わりに。_
実行中にエラーが発生した場合
`pip install coconut`
、追加してみてください
`--user`
または実行中
```
pip install --no-deps --upgrade coconut "pyparsing<3"
```
これにより、Coconutは純粋なPython [
`pyparsing`
](https://github.com/pyparsing/pyparsing) モジュールの代わりに、より高速な [
`cPyparsing`
](https://github.com/evhub/cpyparsing) モジュール。それでもエラーが発生する場合は、代わりに [conda の使用](
`pip install coconut`
動作しますが、
`coconut`
コマンドを実行する前に、Coconutのインストール場所が
`PATH`
環境変数。UNIXでは、
`/usr/local/bin`
(それなし
`--user`
) または
`${HOME}/.local/bin/`
(と
`--user`
)。
[
`conda`
](https://conda.io/docs/) の代わりに
`pip`
Pythonパッケージを管理するには、Coconutをインストールすることもできます。
`conda`
. [インストールする
`conda`
](https://conda.io/miniconda.html) でコマンドラインプロンプトを開き、次のように入力します。
```
conda config --add channels conda-forge
conda install coconut
```
適切に作成して構築する
`conda`
[ココナッツの
`conda-forge`
フィードストック](https://github.com/conda-forge/coconut-feedstock)。
_注: ココナッツの
`conda`
レシピの使用
`pyparsing`
それよりも
`cPyparsing`
、Coconutを経由したインストールに比べてパフォーマンスが低下する可能性があります。
`pip`
._
[Homebrew](https://brew.sh/) を使用する場合は、Coconut をインストールすることもできます。
`brew`
```
brew install coconut
```
_注: Coconut の Homebrew フォーミュラは、最新バージョンの Coconut と常に同じとは限りません。_
Coconut にはオプションの依存関係もあり、次のように入力してインストールできます。
```
pip install coconut[name_of_optional_dependency]
```
または、複数のオプションの依存関係をインストールするには、
```
pip install coconut[opt_dep_1,opt_dep_2]
```
オプションの依存関係の完全なリストは次のとおりです:
-
`all`
: 以下のすべての別名 (これは、Coconut の完全な機能バージョンをインストールする場合に推奨される方法です)。
-
`jupyter`
/
`ipython`
: の使用を可能にします
`--jupyter`
/
`--ipython`
フラグ。
-
`kernel`
: 軽量サブセット
`jupyter`
Coconut の [Jupyter カーネル](
-
`watch`
: の使用を可能にします
`--watch`
フラグ。
-
`mypy`
: の使用を可能にします
`--mypy`
フラグ。
-
`pyright`
: の使用を可能にします
`--pyright`
フラグ。
-
`xonsh`
: ココナッツの[
`xonsh`
サポート](
-
`numpy`
: Coconutの[
`numpy`
統合](
-
`jupyterlab`
: Coconut で [JupyterLab](https://github.com/jupyterlab/jupyterlab) を使用するために必要なものをすべてインストールします。
-
`jupytext`
: Coconut で [Jupytext](https://github.com/mwouts/jupytext) を使用するために必要なものをすべてインストールします。
または、Coconut の最新かつ最高のバージョンをテストしたい場合は、次のように入力します。
```
pip install coconut-develop
```
これはCoconutの[
`develop`
ブランチ](https://github.com/evhub/coconut/tree/develop)。オプションの依存関係のインストールは、上記と同じ方法でサポートされています。現在の開発ビルドの詳細については、[このドキュメントの開発バージョン](http://coconut.readthedocs.io/en/develop/DOCS.html)を参照してください。注意:
`coconut-develop`
不安定になる可能性があります。バグを見つけた場合は、[新しい問題を作成](https://github.com/evhub/coconut/issues/new)して報告してください。
_注: 既存のリリースバージョンをお持ちの場合は、
`coconut`
インストールするには、
`pip uninstall coconut`
インストールする前に
`coconut-develop`
._
```{contents}
---
local:
depth: 1
---
```
#### 使用法
```
coconut [-h] [--and source [dest ...]] [-v] [-t version] [-i] [-p] [-a] [-l]
[--no-line-numbers] [-k] [-w] [-r] [-n] [-d] [-q] [-s] [--no-tco] [--no-wrap-types]
[-c code] [-j processes] [-f] [--minify] [--jupyter ...] [--mypy ...] [--pyright]
[--argv ...] [--tutorial] [--docs] [--style name] [--vi-mode]
[--recursion-limit limit] [--stack-size kbs] [--fail-fast] [--no-cache]
[--site-install] [--site-uninstall] [--verbose] [--trace] [--profile]
[source] [dest]
```
```
source path to the Coconut file/folder to compile
dest destination directory for compiled files (defaults to
the source directory)
```
```
-h, --help show this help message and exit
--and source [dest ...]
add an additional source/dest pair to compile (dest is optional)
-v, -V, --version print Coconut and Python version information
-t version, --target version
specify target Python version (defaults to universal)
-i, --interact force the interpreter to start (otherwise starts if no other command is
given) (implies --run)
-p, --package compile source as part of a package (defaults to only if source is a
directory)
-a, --standalone, --stand-alone
compile source as standalone files (defaults to only if source is a single
file)
-l, --line-numbers, --linenumbers
force enable line number comments (--line-numbers are enabled by default
unless --minify is passed)
--no-line-numbers, --nolinenumbers
disable line number comments (opposite of --line-numbers)
-k, --keep-lines, --keeplines
include source code in comments for ease of debugging
-w, --watch watch a directory and recompile on changes
-r, --run execute compiled Python
-n, --no-write, --nowrite
disable writing compiled Python
-d, --display print compiled Python
-q, --quiet suppress all informational output (combine with --display to write
runnable code to stdout)
-s, --strict enforce code cleanliness standards
--no-tco, --notco disable tail call optimization
--no-wrap-types, --nowraptypes
disable wrapping type annotations in strings and turn off 'from __future__
import annotations' behavior
-c code, --code code run Coconut passed in as a string (can also be piped into stdin)
-j processes, --jobs processes
number of additional processes to use (defaults to 'sys') (0 is no
additional processes; 'sys' uses machine default)
-f, --force force re-compilation even when source code and compilation parameters
haven't changed
--minify reduce size of compiled Python
--jupyter ..., --ipython ...
run Jupyter/IPython with Coconut as the kernel (remaining args passed to
Jupyter)
--mypy ... run MyPy on compiled Python (remaining args passed to MyPy) (implies
--package --line-numbers)
--pyright run Pyright on compiled Python (implies --package)
--argv ..., --args ...
set sys.argv to source plus remaining args for use in the Coconut script
being run
--tutorial open Coconut's tutorial in the default web browser
--docs, --documentation
open Coconut's documentation in the default web browser
--style name set Pygments syntax highlighting style (or 'list' to list styles)
(defaults to COCONUT_STYLE environment variable if it exists, otherwise
'default')
--vi-mode, --vimode enable vi mode in the interpreter (currently set to False) (can be
modified by setting COCONUT_VI_MODE environment variable)
--recursion-limit limit, --recursionlimit limit
set maximum recursion depth in compiler (defaults to 1920) (when
increasing --recursion-limit, you may also need to increase --stack-size;
setting them to approximately equal values is recommended)
--stack-size kbs, --stacksize kbs
run the compiler in a separate thread with the given stack size in
kilobytes
--fail-fast causes the compiler to fail immediately upon encountering a compilation
error rather than attempting to continue compiling other files
--no-cache disables use of Coconut's incremental parsing cache (caches previous
parses to improve recompilation performance for slightly modified files)
--site-install, --siteinstall
set up coconut.api to be imported on Python start
--site-uninstall, --siteuninstall
revert the effects of --site-install
--verbose print verbose debug output
--trace print verbose parsing data (only available in coconut-develop)
--profile collect and print timing info (only available in coconut-develop)
```
Coconut ファイルをスクリプトとして実行するために、Coconut は次のコマンドを提供します
```
coconut-run <source> <args>
```
別名として
```
coconut --quiet --target sys --keep-lines --run <source> --argv <args>
```
静かにコンパイルして実行する
`<source>`
スクリプトに追加の引数を渡し、
`python`
コマンドは機能します。代わりに、追加のコンパイル引数を Coconut 自体に渡します (例:
`--no-tco`
)、それらを
`<source>`
ファイル。
`coconut-run`
ファイルではなくディレクトリをコンパイルして実行するために使用することができ、これも
`python`
コマンドは機能します。具体的には、Coconutはディレクトリをコンパイルし、
`__main__.coco`
そのディレクトリ内に存在している必要があります。
`coconut-run`
Unix のシェバン行で使用して Coconut スクリプトを作成するには、スクリプトの先頭に次の行を追加します。
```bash
#!/usr/bin/env coconut-run
```
`coconut-run`
常に[自動コンパイル](
`coconut-run`
さらに、コンパイルパラメータ(例:
`--no-tco`
)で使用される
`coconut-run`
渡され、自動コンパイルに使用されます。
Python 3.4 以降では、
`coconut-run`
を使用します
`__coconut_cache__`
コンパイルされたPythonをキャッシュするディレクトリ。
`__coconut_cache__`
常に削除されます
`__file__`
.
Coconut ソースファイルは、コンパイラが認識できるように、拡張子を使用する必要があります。
`.coco`
.
ココナッツが
`.coco`
ファイルの場合、同じ名前の別のファイルにコンパイルされますが、
`.py`
の代わりに
`.coco`
コンパイルされたコードが格納されます。
以外の拡張子の場合
`.py`
コンパイルされたファイルに拡張子が必要な場合は、その拡張子を
`.coco`
ソースファイル名に含まれており、
`.py`
コンパイルされたファイルの場合。たとえば、
`name.coco`
コンパイルすると
`name.py`
、 一方
`name.abc.coco`
コンパイルすると
`name.abc`
.
コンパイルされたファイルは
`coconut`
コマンドラインユーティリティは、コンパイルパラメータによって異なります。ファイルのディレクトリ全体をコンパイルする場合(コンパイラは、
`.coco`
ファイル)、
`__coconut__.py`
必要な関数を格納するためのファイルが作成されます(パッケージモード)。一方、単一のファイルのみがコンパイルされる場合、その情報はファイル内のヘッダー内に格納されます(スタンドアロンモード)。スタンドアロンモードは、インポートに伴うオーバーヘッドを排除するため、単一のファイルに適しています。
`__coconut__.py`
しかし、パッケージモードは、同じCoconutヘッダーコードを各ファイルで再度実行する必要がなくなるため、大きなパッケージに適しています。
`__coconut__.py`
.
デフォルトでは、
`source`
コマンドラインユーティリティの引数がファイルの場合、スタンドアロンコンパイルを実行しますが、ディレクトリの場合は、すべてのディレクトリを再帰的に検索します。
`.coco`
ファイルを選択し、それらに対してパッケージコンパイルを実行します。したがって、ほとんどの場合、Coconutが自動的に選択したモードが正しいものになります。ただし、次のような追加ファイルがないことが非常に重要な場合は、
`__coconut__.py`
たとえば、コマンドラインユーティリティは、
`--package`
(
`-p`
) そして
`--standalone`
(
`-a`
) フラグを使用します。
Coconut 構文は最新の Python 3 に基づいていますが、Coconut コードはユニバーサル モード (デフォルト) でコンパイルされます。
`--target`
)とCoconutコンパイラ自体は、どのPythonバージョンでも動作するはずです。
`>= 2.6`
に
`2.x`
支店または
`>= 3.2`
に
`3.x`
ブランチ(および [CPython](https://www.python.org/) または [PyPy](http://pypy.org/))で使用できます。
Coconut の組み込みを Python バージョン間で共通にするために、Coconut は、**Python 2 の組み込みを Python 3 の対応するもので自動的に上書きする** など、後のバージョンにのみ存在する組み込みをすべての Python バージョンで利用できるようにしています。さらに、Coconut は [最適化と機能強化のために一部の Python 3 の組み込みを上書きします](
`py_`
具体的には、上書きされる組み込み関数は次のとおりです:
-
`py_bytes`
-
`py_chr`
-
`py_dict`
-
`py_hex`
-
`py_input`
-
`py_int`
-
`py_map`
-
`py_object`
-
`py_oct`
-
`py_open`
-
`py_print`
-
`py_range`
-
`py_str`
-
`py_super`
-
`py_zip`
-
`py_filter`
-
`py_reversed`
-
`py_enumerate`
-
`py_raw_input`
-
`py_xrange`
-
`py_repr`
-
`py_breakpoint`
-
`py_min`
-
`py_max`
_注: ココナッツの
`repr`
削除しようとするので、少し難しいかもしれません
`u`
Python 2 では Unicode 文字列の before repr をコンパイルできますが、Unicode 文字列がネストされている場合は必ずしも実行できるとは限りません。_
標準ライブラリの互換性のために、**Coconut は Python 3 名のインポートを Python 2 名のインポートに自動的にマッピングします**。したがって、Python 3 名だけが使用されている場合、Coconut は Python 2 から Python 3 に名前が変更された標準ライブラリ モジュールを自動的に処理します。ただし、Python 3 にのみ存在するモジュールまたはパッケージの場合、Coconut には互換性を維持する方法がありません。
最後に、Coconut は Python 3 固有の構文をその汎用的な同等の構文にコンパイルしようとしますが、次の構文は Python 2 に同等の構文がなく、少なくとも 1 つ以上のターゲットの指定が必要です。
`3`
使用するもの:
-
`nonlocal`
キーワード、
- キーワードのみの関数パラメータ(ユニバーサルコードには [パターンマッチング関数定義](
-
`async`
そして
`await`
ステートメント (特定のターゲットが必要です。Coconut はターゲット バージョンに基づいて異なる [バックポート](
-
`:=`
代入式(
`--target 3.8`
)、
- 位置のみの関数パラメータ(ユニバーサルコードには[パターンマッチング関数定義](
`--target 3.8`
)、
-
`a[x, *y]`
可変長ジェネリック構文(ユニバーサルコードには[型パラメータ構文](
`--target 3.11`
)、 そして
-
`except*`
複数の例外文(
`--target 3.11`
)。
_注: ココナッツは、
`__bool__`
そして [
`__set_name__`
](https://docs.python.org/3/reference/datamodel.html
コンパイルされたコードが実行される Python のバージョンが事前にわかっている場合は、ターゲットを次のように指定する必要があります。
`--target`
指定されたターゲットは、コンパイルされたコードと、上記で説明した Python 3 固有の構文が許可されるかどうかにのみ影響します。Python 構文がバージョン間で異なる場合、Coconut 構文は常にすべてのターゲットで最新の Python 3 に従います。サポートされているターゲットは次のとおりです:
-
`universal`
、
`univ`
(デフォルト): 以下のいずれでも動作します
-
`2`
、
`2.6`
: Pythonならどれでも動作します
`>= 2.6`
しかし
`< 3`
-
`2.7`
: Pythonならどれでも動作します
`>= 2.7`
しかし
`< 3`
-
`3`
、
`3.2`
: Pythonならどれでも動作します
`>= 3.2`
-
`3.3`
: Pythonならどれでも動作します
`>= 3.3`
-
`3.4`
: Pythonならどれでも動作します
`>= 3.4`
-
`3.5`
: Pythonならどれでも動作します
`>= 3.5`
-
`3.6`
: Pythonならどれでも動作します
`>= 3.6`
-
`3.7`
: Pythonならどれでも動作します
`>= 3.7`
-
`3.8`
: Pythonならどれでも動作します
`>= 3.8`
-
`3.9`
: Pythonならどれでも動作します
`>= 3.9`
-
`3.10`
: Pythonならどれでも動作します
`>= 3.10`
-
`3.11`
: Pythonならどれでも動作します
`>= 3.11`
-
`3.12`
: Pythonならどれでも動作します
`>= 3.12`
-
`3.13`
: Pythonならどれでも動作します
`>= 3.13`
-
`sys`
: 現在の Python バージョンに対応するターゲットを選択します
-
`psf`
: PSF (Python Software Foundation) によって [サポート終了](https://devguide.python.org/versions/) とみなされていない Python であれば動作します
_注: ターゲット指定ではピリオドはオプションです。ターゲット
`27`
ターゲットに相当する
`2.7`
._
`strict`
モード
`--strict`
(
`-s`
(略して)フラグが有効になっている場合、Coconutはコンパイルされるコードに対して追加のチェックを実行します。
`--strict`
新しいCoconutプロジェクトを始める場合は、フラグを設定してください。これにより、よりクリーンなコードを書くことができます。具体的には、
`--strict`
:
- 非推奨の機能を無効にする(コンパイルされたコードで完全に使用不可にする)
`--strict`
)、
- 未使用のインポートに対して警告ではなくエラーを表示します(
`# NOQA`
または
`# noqa`
コメント)、
- 組み込みを上書きするときに警告ではなくエラーを表示する (組み込み名をエスケープするためにバックスラッシュが使用されていない場合)、
- 不足しているときに警告を表示する
`__init__.coco`
コンパイル時にファイルを
`--package`
モード、
- さまざまなスタイルの問題でエラーが発生します (以下のリストを参照)。
原因となるスタイルの問題
`--strict`
エラーが発生する原因は次のとおりです:
- タブとスペースの混在
-
`"hello" "world"`
暗黙的な文字列連結(明示的な
`+`
代わりに)
- の使用
`from __future__`
インポート(Coconutはこれを自動的に行います)
- 継承元
`object`
クラス内(Coconutはこれを自動的に行います)
- 行末のセミコロン
- の使用
`u`
Unicode 文字列を表す (Coconut 文字列はすべて Unicode 文字列です)
-
`f`
- 書式式を含まない文字列
- [ステートメント ラムダ](
- ファイルの末尾に改行がない
- 行末に空白がある
- Python スタイルの使用
`lambda`
ステートメント(代わりに [Coconut のラムダ構文](
- バックスラッシュ継続の使用(代わりに [括弧継続](
- パターンマッチングにおける Python-3.10/PEP-634 スタイルのドット付き名前(Coconut スタイルでは、これらの前に
`==`
)
- の使用
`:`
の代わりに
`<:`
[Coconut の型パラメータ構文](
上記のスタイルの問題の多くは、次の場合でも警告が表示されることに注意してください。
`--strict`
存在しません。
Coconut は、古いバージョンの Python に自動的にバックポートできる新しい Python 機能に加えて、さまざまな外部バックポートも利用できるようにコードを自動的にコンパイルします。これらのバックポートは、必要に応じて Coconut とともに自動的にインストールされ、標準ライブラリが利用できない場合は、Coconut は標準ライブラリの代わりに自動的にそれらを使用します。これらのバックポートは次のとおりです:
- [
`typing`
](https://pypi.org/project/typing/) バックポート用 [
`typing`
](https://docs.python.org/3/library/typing.html)。
- [
`typing_extensions`
](https://pypi.org/project/typing-extensions/) 個々の
`typing`
オブジェクト。
- [
`backports.functools-lru-cache`
](https://pypi.org/project/backports.functools-lru-cache/) バックポート用 [
`functools.lru_cache`
](https://docs.python.org/3/library/functools.html
- [
`exceptiongroup`
](https://pypi.org/project/exceptiongroup/) バックポート用 [
`ExceptionGroup`
そして
`BaseExceptionGroup`
](https://docs.python.org/3/library/Exceptions.html
- [
`dataclasses`
](https://pypi.org/project/dataclasses/) バックポート用 [
`dataclasses`
](https://docs.python.org/3/library/dataclasses.html)。
- [
`aenum`
](https://pypi.org/project/aenum) バックポート用 [
`enum`
](https://docs.python.org/3/library/enum.html)。
- [
`async_generator`
](https://github.com/python-trio/async_generator) バックポート用 [
`async`
ジェネレータ](https://peps.python.org/pep-0525/) と [
`asynccontextmanager`
](https://docs.python.org/3/library/contextlib.html
- [
`trollius`
](https://pypi.python.org/pypi/trollius) バックポート用 [
`async`
/
`await`
](https://docs.python.org/3/library/asyncio-task.html) および [
`asyncio`
](https://docs.python.org/3/library/asyncio.html)。
コンパイルされた Coconut コードを配布する際に、これらのバックポートのいずれかを使用する場合は、必要なバックポート モジュールが依存関係として含まれていることを確認する必要があることに注意してください。
```{contents}
---
local:
depth: 2
---
```
Coconut 構文の強調表示をサポートするテキスト エディターは次のとおりです。
- **VSCode**: [Coconut (公式)](https://marketplace.visualstudio.com/items?itemName=evhub.coconut) をインストールします (**VSCodium** の場合は、代わりに Open VSX [こちら](https://open-vsx.org/extension/evhub/coconut) からインストールします)。
- **SublimeText**: 以下の SublimeText セクションを参照してください。
- **Spyder** (または **Pygments** をサポートするその他のエディター): 以下の Pygments セクションを参照してください。
- **Vim**: [
`coconut.vim`
](https://github.com/manicmaniac/coconut.vim) を参照してください。
- **Emacs**: [ を参照してください。
`emacs-coconut`
](https://codeberg.org/kobarity/emacs-coconut)/[
`emacs-ob-coconut`
](https://codeberg.org/kobarity/emacs-ob-coconut)。
- **Atom**: [ を参照してください。
`language-coconut`
](https://github.com/enilsen16/language-coconut)。
上記のいずれもうまくいかない場合は、CoconutをPythonとして扱うこともできます。エディタを設定して、すべての
`.coco`
ファイルを Python として保存すれば、ほとんどのコードが適切にハイライト表示されるはずです (たとえば、IntelliJ IDEA の場合は [ファイル タイプの登録](https://www.jetbrains.com/help/idea/creating-and-registering-file-types.html) を参照してください)。
SublimeText の Coconut 構文ハイライトには、SublimeText の標準パッケージ マネージャーである [Package Control](https://packagecontrol.io/installation) がインストールされている必要があります。インストールが完了したら、次の操作を行うだけです。
1. を押して SublimeText コマンド パレットを開きます。
`Ctrl+Shift+P`
(または
`Cmd+Shift+P`
Macの場合)、
2. 入力してEnter
`Package Control: Install Package`
、そして
3. 最後に入力してEnter
`Coconut`
.
すべてが正常に動作していることを確認するには、
`.coco`
ファイルを確認し、
`Coconut`
右下隅に表示されます。
`Plain Text`
クリックして選択
`Open all with current extension as...`
表示されたメニューの一番上にある
`Coconut`
.
_注: SublimeText の Coconut 構文強調表示は、[sublime-coconut](https://github.com/evhub/sublime-coconut) パッケージによって提供されます。_
同じ
`pip install coconut`
Coconutコマンドラインユーティリティをインストールするコマンドは、
`coconut`
Pygments lexer。このlexerの使い方は、使用しているPygments対応アプリケーションによって異なりますが、一般的には
`.coco`
ファイル拡張子(Spyderではこれで十分です)および/または入力
`coconut`
ハイライトされている言語として、Pygments がそれを理解できるはずです。
たとえば、このドキュメントは [Sphinx](http://www.sphinx-doc.org/en/stable/) で生成されており、次の行を追加することで構文のハイライトが作成されます。
```coconut_python
highlight_language = "coconut"
```
ココナッツへ
`conf.py`
.
[IPython](http://ipython.org/) ([Jupyter](http://jupyter.org/) フレームワーク用の Python カーネル) ノートブックまたはコンソールを使用する場合、Coconut を Jupyter カーネルまたは IPython 拡張機能として使用できます。
Coconut をカーネルとして使用する場合、コンソールまたはノートブック内のすべてのコードは、評価のために Python ではなく Coconut に直接送信されます。それ以外の場合、Coconut カーネルは、次のサポートを含め、IPython カーネルとまったく同じように動作します。
`%magic`
コマンド。
Coconutをインストールするだけで、
`Coconut`
カーネルをJupyter/IPythonノートブックに追加します。ただし、Coconutカーネルへのアクセスに問題がある場合は、特別なコマンド
`coconut --jupyter install`
再インストールします
`Coconut`
カーネルが現在のPythonを使用していることを確認し、追加のカーネルを追加します
`Coconut (Default Python)`
、
`Coconut (Default Python 2)`
、 そして
`Coconut (Default Python 3)`
それぞれ、次のようにアクセス可能なPythonを使用します。
`python`
、
`python2`
、 そして
`python3`
(これらのカーネルはコンソールで次のようにアクセス可能です
`coconut_py`
、
`coconut_py2`
、 そして
`coconut_py3`
ココナッツはまた、
`coconut --jupyter install --user`
ユーザーのインストール用に。さらに、Coconutカーネルは[
`nb_conda_kernels`
](https://github.com/Anaconda-Platform/nb_conda_kernels) を使用すると、ある Conda 環境の Coconut カーネルに別の Conda 環境からアクセスできるようになります。
Coconut カーネルは常に次のパラメータを使用してコンパイルされます。
`--target sys --line-numbers --keep-lines --no-wrap-types`
.
Coconut では次のコマンドも提供されています:
-
`coconut --jupyter notebook`
Coconut カーネルが利用可能であることを確認し、Jupyter/IPython ノートブックを起動します。
-
`coconut --jupyter console`
Coconut カーネルを使用して Jupyter/IPython コンソールを起動します。
-
`coconut --jupyter lab`
は、Coconut カーネルが使用可能であることを確認し、[JupyterLab](https://github.com/jupyterlab/jupyterlab) を起動します。
さらに、[Jupytext](https://github.com/mwouts/jupytext) には Coconut カーネルの特別なサポートが含まれており、Coconut には [Papermill](https://papermill.readthedocs.io/en/latest/) の特別なサポートが含まれています。
Coconut を拡張機能として使用する場合、特別なマジック コマンドによって、IPython ではなく Coconut を使用して評価されるコード スニペットが送信されますが、デフォルトでは IPython が引き続き使用されます。
行 magic
`%load_ext coconut`
Coconutを拡張機能として読み込み、
`%coconut`
そして
`%%coconut`
マジックとココナッツの組み込み機能を追加します。
`%coconut`
ラインマジックはデフォルトのパラメータでCoconutのラインを実行し、
`%%coconut`
ブロックマジックは最初の行でコマンドライン引数を受け取り、それらのパラメータを使用してセルの残りの部分で提供される Coconut コードを実行します。
_注: 通常の Coconut コマンドラインとは異なり、
`%%coconut`
デフォルトは
`sys`
ターゲットではなく
`universal`
target._
Coconut は [MyPy](http://mypy-lang.org/) と統合して、Coconut のすべての組み込み関数を含むオプションの静的型チェックを提供します。
`--mypy`
に
`coconut`
MyPy統合を有効にするには、最後の引数としてのみ渡すように注意してください。
`--mypy`
渡される
`mypy`
、ココナッツではありません。
実行することもできます
`mypy`
—またはその他の静的型チェッカー—をコンパイル済みの Coconut に直接実行します。ただし、静的型チェッカーが必要なスタブ ファイルを見つけられない場合は、次の操作が必要になる場合があります。
1. 実行
`coconut --mypy install`
そして
2. 選択した静的型チェッカーに、
`~/.coconut_stubs`
スタブファイル用(
`mypy`
、これは[
`MYPYPATH`
](https://mypy.readthedocs.io/en/latest/running_mypy.html
チェック可能な型注釈付きのコードを配布するには、以下を含める必要があります。
`coconut`
依存関係として(ただし
`--no-deps`
インストールは問題ないはずです)。インストールには必要なスタブファイルを用意する必要があるためです。また、[
`py.typed`
](https://peps.python.org/pep-0561/) ファイル。
MyPy ほどサポートされていませんが、Coconut には [Pyright](https://github.com/microsoft/pyright) サポートも組み込まれています。
`--pyright`
コンパイルされたすべてのコードに対してPyrightを自動的に実行します。Pyrightオプションを調整するには、コマンドラインで渡すのではなく、設定をファイルに追加します。
`~/.coconut_pyrightconfig.json`
(初回は自動生成されます
`coconut --pyright`
が実行されます)。
チェックする型をコードに明示的に注釈付けするために、Coconut は (すべての Python バージョンで) 以下をサポートしています:
* [Python 3 関数型注釈](https://www.python.org/dev/peps/pep-0484/)、
* [Python 3.6 変数型注釈](https://www.python.org/dev/peps/pep-0526/)、
* [Python 3.12 型パラメータ構文](
`data`
型](
* Coconut 独自の [拡張型注釈構文](
* Coconut の [プロトコル交差演算子](
デフォルトでは、すべての型注釈は Python 2 互換の型コメントにコンパイルされるため、どのバージョンの Python でもすべて動作します。
場合によっては、MyPy が特定の Coconut 構造の処理方法を認識できないことがあります。たとえば、
`addpattern`
. については
`addpattern`
この場合は、
`--allow-redefinition`
MyPyに(つまり実行
`coconut <args> --mypy --allow-redefinition`
)、ただし、場合によっては
`--allow-redefinition`
十分ではないかもしれません。その場合は、[
`TYPE_CHECKING`
](
`# type: ignore`
MyPy が問題視している行を生成している Coconut 行にコメントを追加すると、生成されたすべての行にコメントが追加されます。
Coconut は以下もサポートしています
`--mypy`
(ただし
`--pyright`
) をインタープリターに組み込み、前の行のコンテキストで各新しいコード行をインテリジェントにスキャンして、新しく導入された MyPy エラーを検出します。例:
```coconut_pycon
>>> a: str = count()[0]
<string>:14: error: Incompatible types in assignment (expression has type "int", variable has type "str")
>>> reveal_type(a)
0
<string>:19: note: Revealed type is 'builtins.unicode'
```
_詳細については
`reveal_type`
、 見る [
`reveal_type`
そして
`reveal_locals`
](
`numpy`
統合
[
`numpy`
](https://numpy.org/)オブジェクトをCoconutでコンパイルすると、すべてのコンパイル済みCoconutコードは、よりよく統合するためにいくつかの特別な処理を実行します。
`numpy`
(もし
`numpy`
コード実行時にインポートできます)。具体的には:
- Coconut の [多次元配列リテラルと配列連結構文](
`numpy`
オブジェクト、高速の使用を含む
`numpy`
連結方法(指定されている場合)
`numpy`
配列ではなく、CoconutのデフォルトのPythonリストのリスト用に構築されたはるかに遅い実装です。
- Coconutの組み込み関数の多くには特別なものが含まれています
`numpy`
サポート、具体的には:
* [
`fmap`
](
`numpy.vectorize`
](https://numpy.org/doc/stable/reference/generated/numpy.vectorize.html) をマッピングする
`numpy`
配列。
* [
`multi_enumerate`
](
`numpy`
配列。
* [
`cartesian_product`
](
`numpy`
配列として
`numpy`
配列。
* [
`all_equal`
](
`numpy`
配列は同じです。
- [
`numpy.ndarray`
](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) は [
`collections.abc.Sequence`
](https://docs.python.org/3/library/collections.abc.html
-
`numpy`
オブジェクトは、Coconut の [暗黙の係数構文](
`A B**2`
略語
`A * B**2`
いつ
`A`
そして
`B`
は
`numpy`
配列(注:**そうではありません**
`A @ B**2`
)。
- ココナッツは
`@`
行列の乗算
`numpy`
すべてのPythonバージョンで配列を提供するだけでなく、
`(@)`
[演算子関数](
さらに、Coconut は [
`pandas`
](https://pandas.pydata.org/)、[
`xarray`
](https://docs.xarray.dev/en/stable/)、[
`pytorch`
](https://pytorch.org/)、および[
`jax.numpy`
](https://jax.readthedocs.io/en/latest/jax.numpy.html) オブジェクト。
`xonsh`
サポート
Coconut は [
`xonsh`
](https://xon.sh/)を使用すると、コマンドラインから直接Coconutコードを使用できます。
`xonsh`
、単に
`pip install coconut`
Coconut構文の使用を有効にするには、
`xonsh`
シェル。特にインストールされている
`xonsh`
バージョン、追加
`xontrib load coconut`
あなたの[
`xonshrc`
](https://xon.sh/xonshrc.html) ファイルが必要になる場合があります。
Coconut の使用例については、
`xonsh`
```
user@computer ~ $ xontrib load coconut
user@computer ~ $ cd ./files
user@computer ~ $ $(ls -la) |> .splitlines() |> len
30
```
コンパイルでは常に [Coconut Jupyter カーネル](
Coconut が
`xonsh`
、
`@(<code>)`
構文と
`execx`
コマンドはPythonコードでのみ機能し、Coconutコードでは機能しません。また、Coconutは個々のコマンドのみをコンパイルします。Coconutは
`.xonshrc`
またはその他
`.xsh`
ファイル。
```{contents}
---
local:
depth: 1
---
```
優先順位の高い順に並べると、Coconut でサポートされている演算子は次のとおりです。
```
====================== ==========================
Symbol(s) Associativity
====================== ==========================
await x n/a
** right (allows unary)
f x n/a
+, -, ~ unary
*, /, //, %, @ left
+, - left
<<, >> left
& left
&: yes
^ left
| left
:: yes (lazy)
.. yes
a `b` c, left (captures lambda)
all custom operators
?? left (short-circuits)
..>, <.., ..*>, <*.., n/a (captures lambda)
..**>, <**.., etc.
|>, <|, |*>, <*|, left (captures lambda)
|**>, <**|, etc.
==, !=, <, >,
<=, >=,
in, not in,
is, is not n/a
not unary
and left (short-circuits)
or left (short-circuits)
x if c else y, ternary (short-circuits)
if c then x else y
=> right
====================== ==========================
```
例えば、加算はパイプよりも優先順位が高いので、
`x |> y + z`
は、
`x |> (y + z)`
.
ココナッツはシンプルでクリーンな
`=>`
Pythonの
`lambda`
ステートメント。
`=>`
演算子は
`(parameters) => expression`
(または
`parameter => expression`
(1引数のラムダの場合)。この演算子は古いステートメントと同じ優先順位を持ち、ラムダを括弧で囲む必要があることが多く、右結合になります。
さらに、Coconut は、
`=>`
フォームの演算子
`(=> expression)`
、これは次の式と同等である。
`((_=None) => expression)`
、これは暗黙のラムダを引数が不要な場合と、1つの引数(
`_`
) が必要です。
_注: 通常のラムダ構文が不十分な場合、Coconut は [ステートメント ラムダ](
_非推奨:
`->`
代替として使用することができます
`=>`
、 けれど
`->`
ベースのラムダは、Coconut の [拡張型注釈構文](
Python では、ラムダは見苦しく、かさばるため、
`lambda`
関数が構築されるたびに書き出される必要があります。インライン関数がほとんど必要ない場合は問題ありませんが、関数型プログラミングではインライン関数は不可欠なツールです。
ラムダ形式 (ラムダ式) は、式と同じ構文上の位置にあります。ラムダ式は匿名関数を作成するための省略形です。式
`(arguments) => expression`
関数オブジェクトを生成します。名前のないオブジェクトは、次のように定義された関数オブジェクトのように動作します。
```coconut
def <lambda>(arguments):
return expression
```
ラムダ形式で作成された関数には、ステートメントや注釈を含めることはできません。
**Coconut:**
```coconut
dubsums = map((x, y) => 2*(x+y), range(0, 10), range(10, 20))
dubsums |> list |> print
```
**Python:**
```coconut_python
dubsums = map(lambda x, y: 2*(x+y), range(0, 10), range(10, 20))
print(list(dubsums))
```
Coconut は暗黙のラムダもサポートしており、ラムダは引数をまったくとらないか、引数を 1 つだけとることができます。暗黙のラムダは、通常の Coconut ラムダ演算子で形成されます。
`=>`
、形式で
`(=> expression)`
これは次の式と同等である。
`((_=None) => expression)`
暗黙のラムダに引数が渡されると、それは
`_`
デフォルト値を置き換える
`None`
.
以下に暗黙のラムダの例を 2 つ示します。最初の例では暗黙の引数を使用しています。
`_`
2 番目はそうではありません。
**単一引数の例:**
```coconut
square = (=> _**2)
```
**引数なしの例:**
```coconut
import random
get_random_number = (=> random.random())
```
_注: 暗黙のラムダ式をネストすると、ラムダ式のスコープに問題が生じる可能性があります。
`_`
各ラムダにパラメータを追加します。暗黙的なラムダのネストは避けることをお勧めします。_
Coconut は
`$`
関数名の直後、関数の呼び出しに使用する開き括弧の前に部分適用を示す記号を付けます。
Coconut の部分適用では、
`?`
引数の部分的な適用をスキップし、その引数の入力を、部分的に適用された関数が呼び出されるまで延期します。これは、引数の順序が最初ではない引数を部分的に適用する場合に便利です。
さらに、
`?`
キーワード引数の値として使用して、位置引数に変換することもできます。たとえば、
`f$(x=?)`
実質的には
```coconut_python
def new_f(x, *args, **kwargs):
kwargs["x"] = x
return f(*args, **kwargs)
```
とは異なり
`functools.partial`
ココナッツの部分的な適用は、
`__name__`
ラップされた関数の。
部分適用、またはカリー化は関数型プログラミングの主流であり、それには十分な理由があります。部分適用により、関数が使用される場所のニーズに合わせて関数を動的にカスタマイズできます。部分適用により、一部の引数を事前に指定した古い関数から新しい関数を作成できます。
新しい
`partial`
呼び出されると、位置引数 _args_ とキーワード引数 _keywords_ で呼び出された _func_ のように動作するオブジェクト。呼び出しにさらに引数が指定された場合、それらは _args_ に追加されます。追加のキーワード引数が指定された場合、それらは _keywords_ を拡張して上書きします。おおよそ次のものと同等です:
```coconut_python
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
```
の
`partial`
オブジェクトは部分的な関数適用に使用され、関数の引数やキーワードの一部を「固定」して、簡略化されたシグネチャを持つ新しいオブジェクトを生成します。
**Coconut:**
```coconut
expnums = range(5) |> map$(pow$(?, 2))
expnums |> list |> print
```
**Python:**
```coconut_python
# unlike this simple lambda, $ produces a pickleable object
expnums = map(lambda x: pow(x, 2), range(5))
print(list(expnums))
```
Coconut は、パイプライン形式の関数適用にパイプ演算子を使用します。すべての演算子は、関数合成パイプと比較の間に優先順位があり、左結合です。すべての演算子は、インプレース バージョンもサポートしています。さまざまな演算子は次のとおりです。
```coconut
(|>) => pipe forward
(|*>) => multiple-argument pipe forward
(|**>) => keyword argument pipe forward
(<|) => pipe backward
(<*|) => multiple-argument pipe backward
(<**|) => keyword argument pipe backward
(|?>) => None-aware pipe forward
(|?*>) => None-aware multi-arg pipe forward
(|?**>) => None-aware keyword arg pipe forward
(<?|) => None-aware pipe backward
(<*?|) => None-aware multi-arg pipe backward
(<**?|) => None-aware keyword arg pipe backward
```
ここでのNone対応パイプ演算子は、オブジェクトを
`Maybe`
どちらかで構成されるモナド
`None`
または与えられたオブジェクト。つまり、
`x |?> f`
は以下と同等である
`None if x is None else f(x)`
パイプされるオブジェクトのみであり、パイプされる関数はパイプされないことに注意してください。
`None`
のために
`None`
認識パイプ。
さらに、必要に応じてパイプ経由で可能な限り多くの操作を実行できるように、いくつかの特別な構文構造がパイプでのみ使用可能です。
*
`async`
パイプ内の関数、星印のないパイプはすべてパイプをサポートしています
`await`
パイプに送られてくる待機可能なものを待機する。
`x |> await`
は以下と同等である
`await x`
.
* 星印のないパイプはすべて、
`(<name> := .)`
([演算子暗黙的部分](
`<name>`
.
* すべてのパイプ演算子は、ラムダの優先順位が低いにもかかわらず、最後の引数としてラムダをサポートします。したがって、
`a |> x => b |> c`
は以下と同等である
`a |> (x => b |> c)`
、 ない
`a |> (x => b) |> c`
.
_注: 操作を複数の行に視覚的に分散するには、[括弧による継続](
Coconut では、パイプを使用して一連の [部分](
```coconut
obj |> .attribute |> .method(args) |> func$(args) |> .[index]
```
これは、操作を、実行された順序で記述できるため、はるかに読みやすくなります。
```coconut_python
func(args, obj.attribute.method(args))[index]
```
どこ
`func`
先頭に置かなければなりません。
Coconut がパイプ構文の各部分を実際の部分適用オブジェクトとしてコンパイルした場合、Coconut スタイルの構文は Python スタイルの構文よりも大幅に遅くなります。したがって、Coconut はそうしません。上記のスタイルの部分または暗黙の部分のいずれかがパイプで使用される場合、可能な限り Python スタイルの構文にコンパイルされ、中間部分適用オブジェクトは生成されません。
これは、次のようなインプレース パイプにも適用されます。
`|>=`
.
**ココナッツ:**
```coconut
def sq(x) = x**2
(1, 2) |*> (+) |> sq |> print
```
```coconut
async def do_stuff(some_data) = (
some_data
|> async_func
|> await
|> post_proc
)
```
**Python:**
```coconut_python
import operator
def sq(x): return x**2
print(sq(operator.add(1, 2)))
```
```coconut_python
async def do_stuff(some_data):
return post_proc(await async_func(some_data))
```
Coconut には 3 つの基本的な関数合成演算子があります。
`..`
、
`..>`
、 そして
`<..`
。 両方
`..`
そして
`<..`
数学スタイルの「逆方向」関数合成を使用します。最初の関数は最後に呼び出され、
`..>`
「前方」関数合成を使用し、最初の関数が最初に呼び出されます。前方および後方関数合成パイプは、同じ式で一緒に使用することはできず(通常のパイプとは異なり)、その間に優先順位があります。
`None`
-合体パイプと通常のパイプ。
`..>`
そして
`<..`
関数合成パイプ演算子には、[通常のパイプ](
```
..> => forwards function composition pipe
<.. => backwards function composition pipe
..*> => forwards multi-arg function composition pipe
<*.. => backwards multi-arg function composition pipe
..**> => forwards keyword arg function composition pipe
<**.. => backwards keyword arg function composition pipe
..?> => forwards None-aware function composition pipe
<?.. => backwards None-aware function composition pipe
..?*> => forwards None-aware multi-arg function composition pipe
<*?.. => backwards None-aware multi-arg function composition pipe
..?**> => forwards None-aware keyword arg function composition pipe
<**?.. => backwards None-aware keyword arg function composition pipe
```
ご了承ください
`None`
-aware関数合成パイプでは、どちらの関数も
`None`
—むしろ、最初に評価された関数の戻り値を
`None`
、その場合
`None`
次の関数を呼び出すのではなく、すぐに返されます。
`..`
演算子の優先順位は
`::`
しかし、インフィックス関数よりも優先順位が高く、
`..>`
パイプ演算子の優先順位は通常のパイプよりも高くなります。
すべての関数合成演算子にはインプレース バージョンもあります (例:
`..=`
)。
関数合成のすべての形式は常に合成の最初の関数を呼び出すため (
`f`
で
`f ..> g`
そして
`g`
で
`f <.. g`
) を合成に渡された引数とまったく同じ引数で実行すると、関数合成のすべての形式で、合成の最初の関数に添付されたすべてのメタデータ (関数の [署名](https://docs.python.org/3/library/inspect.html
_注: 合成の場合
`async`
機能については、[
`and_then`
そして
`and_then_await`
](
**ココナッツ:**
```coconut
fog = f..g
f_into_g = f ..> g
```
**Python:**
```coconut_python
# unlike these simple lambdas, Coconut produces pickleable objects
fog = lambda *args, **kwargs: f(g(*args, **kwargs))
f_into_g = lambda *args, **kwargs: g(f(*args, **kwargs))
```
Coconut は
`$`
イテレータスライスを実行するには、イテレータの直後にスライスの前に記号を付けます。
`it$[:5]`
Coconut のイテレータ スライシングは Python のシーケンス スライシングとほぼ同じように機能し、Coconut の部分適用とほとんど同じように見えますが、括弧の代わりに角括弧が使用されています。
イテレータ スライシングはシーケンス スライシングと同じように機能し、負のインデックスとスライスのサポート、および
`slice`
通常のスライスと同じようにオブジェクトをスライスします。ただし、イテレータ スライスでは、渡された元のイテレータが保持されるという保証はありません (イテレータを保持するには、Coconut の [
`reiterable`
](
Coconut のイテレータ スライスは Python の
`itertools.islice`
、しかし、
`itertools.islice`
ココナッツのイテレータスライスは負のインデックスをサポートしており、オブジェクトの
`__iter_getitem__`
(利用可能な場合は常に使用)または
`__getitem__`
(オブジェクトが
`collections.abc.Sequence`
)。Coconut のイテレータ スライスは、Coconut の組み込みオブジェクトすべてで適切に動作するように最適化されており、目的のスライスを抽出するために実際に必要な各オブジェクトの要素のみを計算します。
**Coconut:**
```coconut
map(x => x*2, range(10**100))$[-1] |> print
```
**Python:**
_複雑なイテレータスライス関数とカスタムオブジェクトの検査なしでは実行できません。Python で必要な定義は Coconut ヘッダーにあります。_
Coconut は
`::`
イテレータ連鎖の演算子。Coconut のイテレータ連鎖は遅延実行され、引数は必要になるまで評価されません。ビットごとの or 呼び出しとインフィックス呼び出しの間に優先順位があります。チェーンは、渡されたイテレータが反復可能である場合にのみ反復可能 (複数回反復して同じ結果を得ることができる) です。インプレース演算子は
`::=`
.
_[lazyリスト](
`a :: b`
は以下と同等である
`flatten((|a, b|))`
._
イテレータの操作をシーケンスの操作と同じくらい簡単にする便利なツールは、複数のイテレータを遅延的に結合できることです。この操作はチェーンと呼ばれ、シーケンスの加算と同等ですが、必要になるまで何も評価されません。
最初のイテレータから要素を返し、それがなくなるまで、次のイテレータに進みます。すべてのイテレータがなくなるまで、繰り返します。連続するシーケンスを 1 つのシーケンスとして扱うために使用されます。チェーンされた入力は遅延的に評価されます。次のものとほぼ同等です。
```coconut_python
def chain(*iterables):
# chain('ABC', 'DEF') --> A B C D E F
for it in iterables:
for element in it:
yield element
```
**ココナッツ:**
```coconut
def N(n=0) = (n,) :: N(n+1) # no infinite loop because :: is lazy
(range(-10, 0) :: N())$[5:15] |> list |> print
```
**Python:**
_遅延連鎖の代わりに複雑な反復子の理解なしには実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
Coconut ではインフィックス関数呼び出しが可能です。関数として評価される式はバックティックで囲まれ、その前または後ろに引数を置くことができます。インフィックス呼び出しは連鎖と
`None`
-coalescing であり、左結合です。
インフィックス呼び出しで使用できる表記法は次のとおりです。
```coconut
x `f` y => f(x, y)
`f` x => f(x)
x `f` => f(x)
`f` => f()
```
さらに、インフィックス記法では、ラムダの優先順位が低いにもかかわらず、最後の引数としてラムダを使用できます。つまり、
``
1つの
`func`
b => c
``
は以下と同等である
`func(a, b => c)`
.
Coconut は、インフィックス関数定義もサポートしており、インフィックス使用を目的とした関数の定義が簡単になります。インフィックス関数定義の構文は次のとおりです。
```coconut
def <arg> `<name>` <arg>:
<body>
```
どこ
`<name>`
関数の名前は
`<arg>`
は関数の引数であり、
`<body>`
関数の本体です。
`<arg>`
デフォルトが含まれている
`<arg>`
括弧で囲む必要があります。
_注: 中置関数定義は、代入やパターン マッチング関数定義と組み合わせることができます。_
関数型プログラミングの一般的な慣用句は、演算子のように動作することを意図した関数を記述し、引数の間に配置して呼び出して定義することです。Coconut の中置構文ではこれが可能です。
**Coconut:**
```coconut
def a `mod` b = a % b
(x `mod` 2) `print`
```
**Python:**
```coconut_python
def mod(a, b): return a % b
print(mod(x, 2))
```
Coconut では、構文を使用して独自のカスタム演算子を宣言できます。
```
operator <op>
```
どこ
`<op>`
は、カスタム演算子として使用したいUnicode文字のシーケンスです。
`operator`
ステートメントはトップレベルに出現する必要があり、その後に続くコードにのみ影響します。
宣言すると、カスタム演算子は [infix function](
`(<op>)`
他の [演算子関数](
宣言後にカスタム演算子を定義するための構文の例をいくつか示します。
```
def x <op> y: ...
def <op> x = ...
match def (x) <op> (y): ...
(<op>) = ...
from module import name as (<op>)
```
カスタム演算子を使用するための構文の例をいくつか示します。
```
x <op> y
x <op> y <op> z
<op> x
x <op>
x = (<op>)
f(<op>)
(x <op> .)
(. <op> y)
match x <op> in ...: ...
match x <op> y in ...: ...
```
さらに、他のモジュールからカスタム演算子をインポートするために、Coconut は次の特別な構文をサポートしています。
```
from <module> import operator <op>
```
カスタム演算子は、正しく解析するために、多くの場合、空白文字 (または演算子関数として使用する場合は括弧) で囲む必要があります。
有効な名前でもあるカスタム演算子が必要な場合は、名前の前にバックスラッシュを使用して、Coconut の [キーワード/変数の曖昧さ回避構文](
_注: Coconut の組み込み [Unicode 演算子の代替](
**Coconut:**
```coconut
operator %%
(%%) = math.remainder
10 %% 3 |> print
operator !!
(!!) = bool
!! 0 |> print
operator log10
from math import \log10 as (log10)
100 log10 |> print
```
**Python:**
```coconut_python
print(math.remainder(10, 3))
print(bool(0))
print(math.log10(100))
```
ココナッツは
`??`
として
`None`
-合体演算子、
`??`
C
`None`
[PEP 505](https://www.python.org/dev/peps/pep-0505/) で提案された、認識演算子。
Coconut の
`??`
演算子は、そのオペランドが
`None`
、そうでなければその右オペランド。式
`foo ?? bar`
次のように評価されます
`foo`
そうでない限り
`None`
、そして
`bar`
もしそうなら、
`None`
-coalescing演算子は短絡的であり、左のオペランドが
`None`
、右オペランドは評価されません。これにより、右オペランドを潜在的に高価な操作にすることができ、不必要なコストは発生しません。
`None`
-coalescing 演算子は、インフィックス関数呼び出しと合成パイプの間に優先順位を持ち、左結合です。
**Coconut:**
```coconut
could_be_none() ?? calculate_default_value()
```
**Python:**
```coconut_python
(lambda result: result if result is not None else calculate_default_value())(could_be_none())
```
インプレース代入演算子は
`??=`
、これは、変数が現在
`None`
。
```coconut
foo = 1
bar = None
foo ??= 10 # foo is still 1
bar ??= 10 # bar is now 10
```
標準で説明されているように
`??`
オペレーター、
`None`
-coalescing代入演算子は、左辺が満たされない限り、右辺を評価しません。
`None`
。
```coconut
baz = 0
baz ??= expensive_task() # right hand side isn't evaluated
```
Coconut では単一の
`?`
属性アクセス、関数呼び出し、部分適用、および(イテレータ)インデックス付けの前に、これまでの評価結果が
`None`
これは「安全ナビゲーション」演算子と呼ばれることもあります。
`None`
メソッドまたは属性のメンバーアクセスのための -aware 演算子の場合、構文は次のようになります。
`obj?.method()`
または
`obj?.attr`
それぞれ。
`obj?.attr`
は以下と同等である
`obj.attr if obj is not None else obj`
これによって、
`AttributeError`
もし
`attr`
属性またはメソッドではありません
`obj`
.
その
`None`
-awareインデックス演算子は通常のインデックスと同様に使用され、
`?[]`
の代わりに
`[]`
。
`seq?[index]`
は、次の式と同等である。
`seq[index] if seq is not None else seq`
この演算子を使用しても、
`IndexError`
もし
`index`
範囲外です
`seq`
.
Coconut は、None 対応の [パイプ演算子](
**Coconut:**
```coconut
could_be_none?.attr # attribute access
could_be_none?(arg) # function calling
could_be_none?.method() # method calling
could_be_none?$(arg) # partial application
could_be_none()?[0] # indexing
could_be_none()?.attr[index].method()
```
**Python:**
```coconut_python
import functools
(lambda result: None if result is None else result.attr)(could_be_none())
(lambda result: None if result is None else result(arg))(could_be_none())
(lambda result: None if result is None else result.method())(could_be_none())
(lambda result: None if result is None else functools.partial(result, arg))(could_be_none())
(lambda result: None if result is None else result[0])(could_be_none())
(lambda result: None if result is None else result.attr[index].method())(could_be_none())
```
Coconut は
`&:`
プロトコルの交差を示す演算子。つまり、2つの[
`typing.Protocol`
s](https://docs.python.org/3/library/typing.html
`Protocol1`
そして
`Protocol1`
、
`Protocol1 &: Protocol2`
は、
`Protocol`
両方の要件を組み合わせた
`Protocol1`
そして
`Protocol2`
.
Coconut のプロトコル交差演算子を使用する推奨方法は、Coconut の [演算子と組み合わせることです。
`Protocol`
s](
`&:`
どこでも働く、オペレーター
`Protocol`
は型注釈内でのみ機能します(つまり、たとえば、次のようにする必要があります。
`type HasAdd = (+)`
単に
`HasAdd = (+)`
)。
Coconut が型注釈をより一般的にどのように処理するかの詳細については、Coconut の [拡張型注釈](
**Coconut:**
```coconut
from typing import Protocol
class X(Protocol):
x: str
class Y(Protocol):
y: str
def foo(xy: X &: Y) -> None:
print(xy.x, xy.y)
type CanAddAndSub = (+) &: (-)
```
**Python:**
```coconut_python
from typing import Protocol, TypeVar, Generic
class X(Protocol):
x: str
class Y(Protocol):
y: str
class XY(X, Y, Protocol):
pass
def foo(xy: XY) -> None:
print(xy.x, xy.y)
T = TypeVar("T", infer_variance=True)
U = TypeVar("U", infer_variance=True)
V = TypeVar("V", infer_variance=True)
class CanAddAndSub(Protocol, Generic[T, U, V]):
def __add__(self: T, other: U) -> V:
raise NotImplementedError
def __sub__(self: T, other: U) -> V:
raise NotImplementedError
def __neg__(self: T) -> V:
raise NotImplementedError
```
Coconut は、さまざまな演算子記号の Unicode 代替をサポートしています。Unicode 代替は比較的わかりやすく、元の記号の外観や意味を反映するように選択されています。
_注: これらは、デフォルトの組み込み Unicode 演算子のみです。Coconut は、独自の演算子を定義するための [カスタム演算子定義](
```
⇒ (\u21d2) => "=>"
→ (\u2192) => "->"
× (\xd7) => "*" (only multiplication)
↑ (\u2191) => "**" (only exponentiation)
÷ (\xf7) => "/" (only division)
÷/ (\xf7/) => "//"
⁻ (\u207b) => "-" (only negation)
≠ (\u2260) or ¬= (\xac=) => "!="
≤ (\u2264) or ⊆ (\u2286) => "<="
≥ (\u2265) or ⊇ (\u2287) => ">="
⊊ (\u228a) => "<"
⊋ (\u228b) => ">"
∩ (\u2229) => "&"
∪ (\u222a) => "|"
« (\xab) => "<<"
» (\xbb) => ">>"
… (\u2026) => "..."
λ (\u03bb) => "lambda"
↦ (\u21a6) => "|>"
↤ (\u21a4) => "<|"
*↦ (*\u21a6) => "|*>"
↤* (\u21a4*) => "<*|"
**↦ (**\u21a6) => "|**>"
↤** (\u21a4**) => "<**|"
?↦ (?\u21a6) => "|?>"
↤? (?\u21a4) => "<?|"
?*↦ (?*\u21a6) => "|?*>"
↤*? (\u21a4*?) => "<*?|"
?**↦ (?**\u21a6) => "|?**>"
↤**? (\u21a4**?) => "<**?|"
∘ (\u2218) => ".."
∘> (\u2218>) => "..>"
<∘ (<\u2218) => "<.."
∘*> (\u2218*>) => "..*>"
<*∘ (<*\u2218) => "<*.."
∘**> (\u2218**>) => "..**>"
<**∘ (<**\u2218) => "<**.."
∘?> (\u2218?>) => "..?>"
<?∘ (<?\u2218) => "<?.."
∘?*> (\u2218?*>) => "..?*>"
<*?∘ (<*?\u2218) => "<*?.."
∘?**> (\u2218?**>) => "..?**>"
<**?∘ (<**?\u2218) => "<**?.."
⏨ (\u23e8) => "e" (in scientific notation)
```
```{contents}
---
local:
depth: 1
---
```
`match`
Coconutは、完全な機能を備えたパターンマッチングを提供します。
`match`
声明。ココナッツ
`match`
構文は[Pythonの
`match`
構文](https://peps.python.org/pep-0636/)。
_注: Coconut のパターンマッチング構文を説明するにあたり、このセクションでは
`match`
ステートメントで説明されていますが、Coconut のパターン マッチングは、[パターン マッチング関数の定義](
`case`
文](
`match data`
](
`match for`
](
match ステートメントは基本構文に従います
`match <pattern> in <value>`
マッチステートメントは、パターンに対して値の一致を試み、成功した場合は、パターン内の変数を値の同じ位置にあるものにバインドし、マッチステートメントの下のコードを実行します。
マッチステートメントは、基本構文で、
`if <cond>`
マッチを実行した後、以下のコードを実行する前に条件をチェックし、
`else`
後に続くステートメントは、
`match`
ステートメントはそうではありません。
Coconut のすべてのパターン マッチングはアトミックであり、一致全体が成功しない限り割り当ては実行されません。
Coconut の一致ステートメント構文は
```coconut
match <pattern> [not] in <value> [if <cond>]:
<body>
[else:
<body>]
```
どこ
`<value>`
一致するアイテムです。
`<cond>`
オプションの追加チェックであり、
`<body>`
上のヘッダーが成功した場合に実行されるコードです。
`<pattern>`
は、大まかに以下のように定義される独自の特別な構文に従います。以下の構文仕様では、括弧はオプションの構文を示し、括弧の後に
`*`
構文が 0 回以上出現する可能性があることを示します。
```coconut
pattern ::= and_pattern ("or" and_pattern)* # match any
and_pattern ::= as_pattern ("and" as_pattern)* # match all
as_pattern ::= infix_pattern ("as" name)* # explicit binding
infix_pattern ::= bar_or_pattern ("`" EXPR "`" [EXPR])* # infix check
bar_or_pattern ::= pattern ("|" pattern)* # match any
base_pattern ::= (
"(" pattern ")" # parentheses
| "None" | "True" | "False" # constants
| NUMBER # numbers
| STRING # strings
| ["as"] NAME # variable binding
| "==" EXPR # equality check
| "is" EXPR # identity check
| DOTTED_NAME # implicit equality check (disabled in destructuring assignment)
| NAME "(" patterns ")" # classes or data types
| "data" NAME "(" patterns ")" # data types
| "class" NAME "(" patterns ")" # classes
| "(" name "=" pattern ... ")" # anonymous named tuples
| "{" pattern_pairs # dictionaries
["," "**" (NAME | "{}")] "}" # (keys must be constants or equality checks)
| ["s" | "f" | "m"] "{"
pattern_consts
["," ("*_" | "*()")]
"}" # sets
| (EXPR) -> pattern # view patterns
| "(" patterns ")" # sequences can be in tuple form
| "[" patterns "]" # or in list form
| "(|" patterns "|)" # lazy lists
| ("(" | "[") # star splits
[patterns ","]
"*" pattern
["," patterns]
["*" pattern
["," patterns]]
(")" | "]")
| [( # sequence splits
"(" patterns ")"
| "[" patterns "]"
) "+"] NAME ["+" (
"(" patterns ")" # this match must be the same
| "[" patterns "]" # construct as the first match
)] ["+" NAME ["+" (
"(" patterns ")" # and same here
| "[" patterns "]"
)]]
| [( # iterable splits
"(" patterns ")"
| "[" patterns "]"
| "(|" patterns "|)"
) "::"] NAME ["::" (
"(" patterns ")"
| "[" patterns "]"
| "(|" patterns "|)"
)] [ "::" NAME [
"(" patterns ")"
| "[" patterns "]"
| "(|" patterns "|)"
]]
| [STRING "+"] NAME # complex string matching
["+" STRING]
["+" NAME ["+" STRING]]
)
```
`match`
ステートメントはパターンを受け取り、パターンに指定された引数のチェックと分解を実行して、パターンと「一致」しようとします。パターンで指定できるさまざまな構成要素とその機能は次のとおりです。
- 変数バインディング:
- 暗黙のバインディング (
`<var>`
): は、何にでも一致し、一致するものにバインドされますが、いくつかの例外があります:
* 同じ変数が複数回使用される場合、各使用が同じ値に一致するかどうかのチェックが実行されます。
* 変数名が
`_`
を使用すると、何もバインドされず、すべてが常にそれに一致するようになります(
`_`
は Coconut の「ワイルドカード」です)。
- 明示的なバインディング (
`<pattern> as <var>`
): バインドします
`<var>`
に
`<pattern>`
.
- 基本チェック:
- 定数、数値、文字列: 引数内の同じ位置にある同じ定数、数値、または文字列にのみ一致します。
- 等価性チェック (
`==<expr>`
): その位置にあるものが
`==`
表現に
`<expr>`
.
- 本人確認(
`is <expr>`
): その位置にあるものが何であれチェックします
`is`
表現
`<expr>`
.
- 任意の関数パターン:
- インフィックスチェック (
``
<パターン>
`<op>`
<式>
``
): 演算子
`<op>$(?, <expr>)`
その位置にあるものに対して呼び出されると、真偽の値を返し、その後一致する
`<pattern>`
。 例えば、
``
x
`isinstance`
整数
``
その位置にあるものが何であれ確認する
`isinstance$(?, int)`
そしてそれを結びつける
`x`
。 もし
`<expr>`
指定されていない場合は、単に確認する
`<op>`
直接ではなく
`<op>$(<expr>)`
さらに、
``
`<op>`
``
代わりに [カスタム演算子](
- パターンの表示 (
`(<expression>) -> <pattern>`
): 通話
`<expression>`
マッチングするアイテムにマッチし、その結果を
`<pattern>`
. [ の場合、一致は失敗します。
`MatchError`
](
`<expression>`
単一のアトムの場合のみ括弧を外すことができます。
- クラスとデータ型の一致:
- クラスまたはデータ型 (
`<name>(<args>)`
): は、ココナッツ
`data`
type](
- データ型 (
`data <name>(<args>)`
): その位置にあるものがデータ型であるかどうかを確認します
`<name>`
そして属性を
`<args>`
。 一般的に、
`data <name>(<args>)`
構築可能なあらゆるデータ型に一致します
`makedata(<name>, <args>)`
位置引数、名前付き引数、デフォルト引数、および星印付き引数のサポートが含まれています。また、属性名の前にドットを付けることで、厳密な属性もサポートします。
`AttributError`
属性が存在しない場合は一致が失敗するのではなく、一致しない (例:
`data MyData(.my_attr=<some_pattern>)`
)。
- クラス (
`class <name>(<args>)`
): [PEP-634 スタイルのクラス マッチング](https://www.python.org/dev/peps/pep-0634/
- 匿名名前付きタプル (
`(<name>=<pattern>, ...)`
): オブジェクトが
`tuple`
指定された長さの、指定された属性を持つ文字列。[匿名
`namedtuple`
s](
- 辞書の分解:
- 辞書 (
`{<key>: <value>, ...}`
): 任意のマッピングに一致します (
`collections.abc.Mapping`
) を、指定されたキーと値パターンに一致する値で結合します。キーは定数または等価チェックである必要があります。
- Rest 付き辞書 (
`{<pairs>, **<rest>}`
): マッピングに一致します (
`collections.abc.Mapping`
)を含む
`<pairs>`
、そして
`dict`
他のすべてを
`<rest>`
。 もし
`<rest>`
は
`{}`
は、マッピングが正確に同じ長さになるように強制します。
`<pairs>`
.
- セット分解:
- セット (
`s{<constants>, *_}`
): セットに一致します (
`collections.abc.Set`
)には、指定された
`<constants>`
ただし、他のアイテムも含まれる場合があります。
`s`
接頭辞と
`*_`
オプションです。
- 固定長セット(
`s{<constants>, *()}`
): は、
`set`
(
`collections.abc.Set`
)には、指定された
`<constants>`
、他には何もありません。
- Frozensets (
`f{<constants>}`
): は、
`frozenset`
(
`frozenset`
)には、指定された
`<constants>`
. 通常の構文または固定長構文を使用できます。
- マルチセット (
`m{<constants>}`
): は [ と一致します
`multiset`
](
`collections.Counter`
)は、少なくとも指定された
`<constants>`
. 通常の構文または固定長構文を使用できます。
- シーケンスの分割:
- リスト (
`[<patterns>]`
)、タプル(
`(<patterns>)`
): はシーケンスのみに一致します (
`collections.abc.Sequence`
)と同じ長さの文字列を生成し、その内容を
`<patterns>`
(ココナッツは自動的に登録されます
`numpy`
配列と
`collections.deque`
オブジェクトをシーケンスとして扱う)。
- 遅延リスト (
`(|<patterns>|)`
): リストやタプルのマッチングと同じですが、Iterable (
`collections.abc.Iterable`
) の代わりにシーケンスを使用します。
- ヘッドテール分割 (
`<list/tuple> + <var>`
または
`(<patterns>, *<var>)`
): シーケンスの先頭を
`<list/tuple>`
/
`<patterns>`
、残りを
`<var>`
、そしてそれを使用される構造の型にします。
- Init-Last 分割 (
`<var> + <list/tuple>`
または
`(*<var>, <patterns>)`
): ヘッドテール分割とまったく同じですが、シーケンスの先頭ではなく末尾で行われます。
- ヘッドラスト分割 (
`<list/tuple> + <var> + <list/tuple>`
または
`(<patterns>, *<var>, <patterns>)`
): ヘッドテールと初期最終分割の組み合わせ。
- 分割の検索 (
`<var1> + <list/tuple> + <var2>`
または
`(*<var1>, <patterns>, *<var2>)`
): 最初に出現する
`<list/tuple>`
/
`<patterns>`
シーケンスで、その前のすべてを
`<var1>`
そしてその後のすべて
`<var2>`
.
- 先頭-最後の検索分割 (
`<list/tuple> + <var> + <list/tuple> + <var> + <list/tuple>`
または
`(<patterns>, *<var>, <patterns>, *<var>, <patterns>)`
): ヘッドテール分割と検索分割の組み合わせ。
- 反復可能な分割 (
`<list/tuple/lazy list> :: <var> :: <list/tuple/lazy list> :: <var> :: <list/tuple/lazy list>`
): 他のシーケンス分解と同じですが、任意の反復可能オブジェクトで機能します (
`collections.abc.Iterable`
)、無限イテレータを含む(イテレータが一致すると、それが[
`reiterable`
](
- 複雑な文字列マッチング (
`<string> + <var> + <string> + <var> + <string>`
): 文字列マッチングは、上記と同じデストラクチャリング オプションをサポートします。
_注: [イテレータ スライシング](
`reiterable`
](
オブジェクトが特定の方法で一致できるかどうかを確認する場合、Coconut は Python の抽象基本クラスを使用します。したがって、カスタム オブジェクトが適切に一致するようにするには、適切な抽象基本クラスに登録することをお勧めします。
**Coconut:**
```coconut
def factorial(value):
match 0 in value:
return 1
else: match n `isinstance` int in value if n > 0: # Coconut allows nesting of statements on the same line
return n * factorial(n-1)
else:
raise TypeError("invalid argument to factorial of: "+repr(value))
3 |> factorial |> print
```
_ショーケース
`else`
ステートメントは、
`else`
Pythonのステートメント:
`else`
対応する一致が失敗した場合にのみステートメントが実行されます。
```coconut
data point(x, y):
def transform(self, other):
match point(x, y) in other:
return point(self.x + x, self.y + y)
else:
raise TypeError("arg to transform must be a point")
point(1,2) |> point(3,4).transform |> print
point(1,2) |> (==)$(point(1,2)) |> print
```
_データ型とデフォルトの等価演算子の一致を示します。ユーザーが定義した値は
`data`
データ型のコンストラクタへの引数を具体的に参照することで、ステートメントを照合し、その内容にアクセスできます。
```coconut
class Tree
data Empty() from Tree
data Leaf(n) from Tree
data Node(l, r) from Tree
case def depth:
case(Tree()) = 0
case(Tree(n)) = 1
case(Tree(l, r)) = 1 + max(depth(l), depth(r))
Empty() |> depth |> print
Leaf(5) |> depth |> print
Node(Leaf(2), Node(Empty(), Leaf(3))) |> depth |> print
```
_データ型と match ステートメントの組み合わせを効果的に使用して、他の関数型プログラミング言語での代数データ型の使用を再現する方法を紹介します。_
```coconut
def duplicate_first([x] + xs as l) =
[x] + l
[1,2,3] |> duplicate_first |> print
```
_パターンマッチングの最も一般的な使用法の1つであるヘッドテール分割を紹介します。
`+ <var>`
(または
`:: <var>`
リストまたはタプルリテラルの末尾にある任意の反復可能要素は、シーケンスの残りの部分と一致させるために使用できます。
```coconut
case def sieve:
case([head] :: tail) =
[head] :: sieve(n for n in tail if n % head)
case((||)) = []
```
_イテレータに対してどのようにマッチするかを示します。具体的には、空のイテレータの場合(
`(||)`
) は最後に来なければなりません。そうでないと、他のパターンがそれに一致する前に、そのケースは反復子全体を使い果たしてしまいます。
```coconut
def odd_primes(p=3) =
(p,) :: filter(=> _ % p != 0, odd_primes(p + 2))
def primes() =
(2,) :: odd_primes()
case def twin_primes:
case(_ :: [p, (.-2) -> p] :: ps) =
[(p, p+2)] :: twin_primes([p + 2] :: ps)
case() =
twin_primes(primes())
twin_primes()$[:5] |> list |> print
```
_反復可能な検索パターンとビュー パターンを使用して、すべての双子素数の反復子を構築する方法を示します。_
**Python:**
_各要素の長い一連のチェックなしでは実行できません
`match`
ステートメント。Python 構文についてはコンパイルされたコードを参照してください。_
`case`
ココナッツ
`case`
ブロックはココナッツの
`match`
複数の実行に関するステートメント
`match`
同じ値に対するステートメントは、そのうちの1つだけが成功するはずです。
`match`
ステートメント内ではmatchステートメントは1つだけ
`case`
ブロックが成功することは決してないので、より一般的な一致はより具体的な一致の下に置く必要があります。
ココナッツ
`case`
ブロックはPython 3.10の[
`case`
ブロック](https://www.python.org/dev/peps/pep-0634) は、Coconut によって追加された追加のパターン マッチング構造をサポートします (Coconut は、3.10 以降だけでなく、すべての Python バージョンで動作することを保証します)。
case ブロック内の各パターンは、一致するものが見つかるまでチェックされ、対応する本体が実行され、case ブロックが終了します。case ブロックの構文は次のとおりです。
```coconut
match <value>:
case <pattern> [if <cond>]:
<body>
case <pattern> [if <cond>]:
<body>
...
[else:
<body>]
```
どこ
`<pattern>`
どれでも
`match`
パターン、
`<value>`
一致するアイテムです。
`<cond>`
オプションの追加チェックであり、
`<body>`
は、上のヘッダーが成功した場合に実行されるコードです。
`in`
の
`match`
声明:それは
`<value>`
で
`case <value>`
その代わりに
`else`
が存在し、一致が成功しない場合は、
`case`
ステートメントは単にスキップされ、[
`match`
ステートメント](
_非推奨: さらに、
`cases`
または
`case`
代わりにトップレベルのキーワードとして使用できます
`match`
そして、そのようなブロックでは
`match`
それぞれのケースに使用されます。
`case`
._
**ココナッツ:**
```coconut
def classify_sequence(value):
out = "" # unlike with normal matches, only one of the patterns
match value: # will match, and out will only get appended to once
case ():
out += "empty"
case (_,):
out += "singleton"
case (x,x):
out += "duplicate pair of "+str(x)
case (_,_):
out += "pair"
case _ is (tuple, list):
out += "sequence"
else:
raise TypeError()
return out
[] |> classify_sequence |> print
() |> classify_sequence |> print
[1] |> classify_sequence |> print
(1,1) |> classify_sequence |> print
(1,2) |> classify_sequence |> print
(1,1,1) |> classify_sequence |> print
```
_ココナッツの使用例
`case`
構文。_
```coconut
cases {"a": 1, "b": 2}:
match {"a": a}:
pass
match _:
assert False
assert a == 1
```
_例
`cases`
キーワードの代わりに_
**Python:**
_それぞれに対して長い一連のチェックを行わないと実行できません
`match`
ステートメント。Python 構文についてはコンパイルされたコードを参照してください。_
`match for`
Coconutはforループ内でパターンマッチングをサポートしており、パターンは反復可能オブジェクト内の各項目と照合されます。構文は次の通りです。
```coconut
[match] for <pattern> in <iterable>:
<body>
```
これは[分割代入](
```coconut
for elem in <iterable>:
match <pattern> = elem
<body>
```
パターンマッチングは、
`async for`
ループ、両方
`async match for`
そして
`match async for`
明示的な構文として許可されます。
**Coconut:**
```
for {"user": uid, **_} in get_data():
print(uid)
```
**Python:**
```
for user_data in get_data():
uid = user_data["user"]
print(uid)
```
`data`
ココナッツ
`data`
キーワードは、不変の代数データ型を作成するために使用され、デストラクチャリング[パターンマッチング](
`fmap`
](
構文は
`data`
ブロックは関数の構文とクラスの構文を組み合わせたものです。最初の行は関数の定義のように見えますが、残りの部分はクラスのように見え、通常はメソッドの定義が含まれています。これは、
`data`
ブロックは実際には Python のクラスとして終わるため、Coconut は指定された引数に基づいて特別な不変のコンストラクタを自動的に作成します。
Coconut のデータ ステートメント構文は次のようになります。
```coconut
data <name>(<args>) [from <inherits>]:
<body>
```
`<name>`
新しいデータ型の名前です。
`<args>`
コンストラクタへの引数と属性名です。
`<body>`
データ型のメソッドを含み、
`<inherits>`
オプションで、必要な基本クラスを含めることができます。
Coconut では、
`<args>`
デフォルトや[型注釈](
`<name>`
Coconut の [型パラメータ構文](
コンストラクタの記述
`data`
タイプは、
`__new__`
方法の代わりに
`__init__`
方法。簡単に書くのに役立つ
`__new__`
メソッドとして、Coconut は [makedata](
サブクラス化
`data`
型は、別の型から継承することで簡単に作成できます。
`data`
文または通常のPython
`class`
通常の
`class`
ステートメントが使用されている場合、新しいサブクラスを不変にするには、次の行を追加する必要があります。
```coconut
__slots__ = ()
```
これはサブクラスの本体のメソッドや属性定義の前に記述する必要があります。
`data`
型の場合、このようなサブクラス化が推奨される方法です。
`data ... from ...`
構文は、ベースクラスのマジックメソッドを新しいマジックメソッドで上書きします。
`data`
タイプ。
[
`namedtuple`
s](
`data`
型は派生され、
`data`
型:
- 型付き等価性を使用する、
- タプルの加算または乗算をサポートしない (
`data`
本文)、
- スター付き、型付き、[パターンマッチング](
- 特別な [パターンマッチング](
[
`namedtuple`
s](https://docs.python.org/3/library/collections.html
`data`
型は、次のようなさまざまな追加メソッドもサポートしています。[
`._asdict()`
](https://docs.python.org/3/library/collections.html
`._replace(**kwargs)`
](https://docs.python.org/3/library/collections.html
Coconut が Python で改善する関数型プログラミングの柱は、値、つまり不変データ型の使用です。不変データは、一度取得すると変更されないことを保証するため非常に便利ですが、Python ではカスタムの不変データ型を作成するのは困難です。Coconut は、次の機能を提供することで、これを非常に簡単にします。
`data`
ブロック。
**ココナッツ:**
```coconut
data vector2(x:int=0, y:int=0):
def __abs__(self):
return (self.x**2 + self.y**2)**.5
v = vector2(3, 4)
v |> print # all data types come with a built-in __repr__
v |> abs |> print
v.x = 2 # this will fail because data objects are immutable
vector2() |> print
```
_構文、機能、不変の性質を紹介します
`data`
型、およびデフォルト引数と型注釈の使用について説明します。
```coconut
data Empty()
data Leaf(n)
data Node(l, r)
case def size:
case(Empty()) = 0
case(Leaf(n)) = 1
case(Node(l, r)) = size(l) + size(r)
size(Node(Empty(), Leaf(10))) == 1
```
_パターンマッチングを使用して分解する方法を紹介します
`data`
種類。_
```coconut
data vector(*pts):
"""Immutable arbitrary-length vector."""
def __abs__(self) =
self.pts |> map$(pow$(?, 2)) |> sum |> pow$(?, 0.5)
def __add__(self, other) =
vector(*other_pts) = other
assert len(other_pts) == len(self.pts)
map((+), self.pts, other_pts) |*> vector
def __neg__(self) =
self.pts |> map$((-)) |*> vector
def __sub__(self, other) =
self + -other
```
_ショーケーススター
`data`
宣言。_
**Python:**
_各データ型の一連のメソッド定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
`match data`
通常に加えて
`data`
ステートメントに加えて、Coconutはパターンマッチングデータステートメントもサポートしており、Coconutのパターンマッチング構文を使用してデータ型のコンストラクタを定義できます。パターンマッチングデータ型は次のようになります。
```
[match] data <name>(<patterns>) [from <base class>]:
<body>
```
どこ
`<patterns>`
は、[パターンマッチング関数](
パターンマッチングデータ型は、さまざまな点で通常のデータ型と異なることを覚えておくことが重要です。まず、パターンマッチング関数と同様に、[
`MatchError`
](
`TypeError`
間違った引数が渡された場合。第二に、パターンマッチングデータ型は星印の付いた引数に対して特別な処理を行いません。したがって、
```
data vec(*xs)
```
反復処理すると、すべての要素が反復処理されます。
`xs`
、 しかし
```
match data vec(*xs)
```
反復処理すると単一の要素のみが返される
`xs`
.
**ココナッツ:**
```
data namedpt(name `isinstance` str, x `isinstance` int, y `isinstance` int):
def mag(self) = (self.x**2 + self.y**2)**0.5
```
**Python:**
_各データ型の一連のメソッド定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
`where`
ココナッツ
`where`
ステートメントの構文は非常に簡単です。
`where`
声明はただ
```
<stmt> where:
<body>
```
実行する
`<body>`
に続く
`<stmt>`
ただし、
`<body>`
のみ利用可能です
`<stmt>`
(ただし、これらは削除されるのではなく、変更されるだけなので、たとえばラムダは引き続きこれらをキャプチャできます)。
**Coconut:**
```coconut
result = a + b where:
a = 1
b = 2
```
**Python:**
```coconut_python
_a = 1
_b = 2
result = _a + _b
```
`async with for`
現代のPythonでは
`async`
コード、例えば[
`contextlib.aclosing`
](https://docs.python.org/3/library/contextlib.html
```coconut_python
async with aclosing(my_generator()) as values:
async for value in values:
...
```
なぜなら、より文法的に単純なものよりも、はるかに安全だからである。
```coconut_python
async for value in my_generator():
...
```
これは特に[
`trio`
](https://github.com/python-trio/trio)は、[
`async`
発電機付き
`async for`
](https://discuss.python.org/t/preventing-yield-inside-certain-context-managers/1091) の代わりに、上記の
`async with ... async for`
[などのユーティリティを使用したパターン
`trio_util.trio_async_generator`
](https://trio-util.readthedocs.io/en/latest/
このパターンは構文的に非常に扱いにくいことが多いため、Coconut ではショートカット構文を提供しています。
```
async with for value in aclosing(my_generator()):
...
```
これはまさに上記のパターンにコンパイルされます。
`async with for`
また、通常のCoconutと同様にパターンマッチングもサポートしています
`for`
loops](
**ココナッツ:**
```coconut
from trio_util import trio_async_generator
@trio_async_generator
async def my_generator():
# yield values, possibly from a nursery or cancel scope
# ...
async with for value in my_generator():
print(value)
```
**Python:**
```coconut_python
from trio_util import trio_async_generator
@trio_async_generator
async def my_generator():
# yield values, possibly from a nursery or cancel scope
# ...
async with my_generator() as agen:
async for value in agen:
print(value)
```
Coconut では、次のキーワードも有効な変数名です:
-
`data`
-
`match`
-
`case`
-
`cases`
-
`addpattern`
-
`where`
-
`operator`
-
`then`
-
`λ`
([Unicodeの代替](
`lambda`
)
Coconut は通常、これら 2 つのユースケースを区別できますが、必要に応じて区別するための特別な構文が用意されています。記述内容が有効な Python 3 として解釈できる場合、Coconut は常にデフォルトでその解釈を優先することに注意してください。
_変数_ を指定するには、次のように名前の前にバックスラッシュを付けます。
`\data`
_キーワード_を指定するには、名前の前にコロンを付けます。
`:match`
.
さらに、変数名をエスケープするためのバックスラッシュ構文は、変数名と[カスタム演算子](
`--strict`
警告](
最後に、このような曖昧さ回避構文は、構文ハイライト機能に何をしているかを知らせるのにも役立ちます。
**Coconut:**
```coconut
\data = 5
print(\data)
```
```coconut
# without the colon, Coconut will interpret this as the valid Python match[x, y] = input_list
:match [x, y] = input_list
```
**Python:**
```coconut_python
data = 5
print(data)
```
```coconut_python
x, y = input_list
```
```{contents}
---
local:
depth: 1
---
```
ステートメント ラムダ構文は、[通常のラムダ構文](
ステートメント ラムダの構文は次のとおりです。
```
[async|match|copyclosure] def (arguments) => statement; statement; ...
```
どこ
`arguments`
標準関数の引数または[パターンマッチング関数の定義](
`statement`
複合文以外の任意の文、つまりその下にコードブロックを開かない任意の文(つまり
`def x => assert x`
大丈夫ですが
`def x => if x: True`
ではありません)。
`async`
、
`match`
、 そして [
`copyclosure`
](
最後の
`statement`
(セミコロンが続かない)文中のラムダは
`expression`
自動的に返されます。
ステートメントラムダは、暗黙的なラムダ構文もサポートしています。
`def => _`
は以下と同等である
`def (_=None) => _`
パターンマッチングとして明示的にマークするなど
`match def (x) => x`
はパターンマッチング関数になります。
さらに、ステートメントラムダのスコープルールは通常のラムダとは少し異なります。ステートメントラムダが、通常のラムダや内包表記などの式ローカル変数を含む式内にある場合、ステートメントラムダは、ステートメントラムダが定義された時点での変数の値を取得します(通常のラムダのように名前空間全体への参照ではありません)。その結果、
`[=> y for y in range(2)] |> map$(call) |> list`
は
`[1, 1]`
、
`[def => y for y in range(2)] |> map$(call) |> list`
は
`[0, 1]`
これは式ローカル変数に対してのみ機能することに注意してください。関数定義時に名前空間全体をコピーするには、[
`copyclosure`
](
ステートメント ラムダは通常のラムダよりも優先順位が低いため、末尾のカンマなどがキャプチャされることに注意してください。混乱を避けるため、ステートメント ラムダは常に独自の括弧で囲む必要があります。
_非推奨: ステートメント ラムダは以下もサポートします
`->`
の代わりに
`=>`
使用する際は注意してください
`->`
、ステートメント本体のラムダ式も使用する必要があります。
`->`
それよりも
`=>`
._
**ココナッツ:**
```coconut
L |> map$(def (x) =>
y = 1/x;
y*(1 - y))
```
**Python:**
```coconut_python
def _lambda(x):
y = 1/x
return y*(1 - y)
map(_lambda, L)
```
標準ラムダよりもステートメント ラムダが使用されるもう 1 つのケースは、ラムダのパラメータが型注釈で型付けされている場合です。ステートメント ラムダは、パラメータに型注釈を追加するために標準の Python 構文を使用します。
```coconut
f = def (c: str) -> None => print(c)
g = def (a: int, b: int) -> int => a ** b
```
_Deprecated: 非推奨の場合
`->`
の代わりに使用される
`=>`
、戻り値の型注釈は使用できません。_
Coconut は、演算子関数の簡単な省略形を使用します。演算子を括弧で囲んで関数を取得します。イテレータの理解と同様に、演算子関数が関数の唯一の引数である場合、関数呼び出しの括弧は演算子関数の括弧としても機能します。
すべての演算子関数は、[暗黙の部分適用](
`(. + 1)`
は以下と同等である
`(=> _ + 1)`
.
関数型プログラミングでよく行われるのは、組み込み演算子の関数バージョンを使用することです。つまり、カリー化、合成、パイプ処理です。これを簡単にするために、Coconut は演算子関数にアクセスするための短縮構文を提供しています。
```coconut
(::) => (itertools.chain) # will not evaluate its arguments lazily
($) => (functools.partial)
(.) => (getattr)
(,) => (*args) => args # (but pickleable)
(+) => (operator.add)
(-) => # 1 arg: operator.neg, 2 args: operator.sub
(*) => (operator.mul)
(**) => (operator.pow)
(/) => (operator.truediv)
(//) => (operator.floordiv)
(%) => (operator.mod)
(&) => (operator.and_)
(^) => (operator.xor)
(|) => (operator.or_)
(<<) => (operator.lshift)
(>>) => (operator.rshift)
(<) => (operator.lt)
(>) => (operator.gt)
(==) => (operator.eq)
(<=) => (operator.le)
(>=) => (operator.ge)
(!=) => (operator.ne)
(~) => (operator.inv)
(@) => (operator.matmul)
(|>) => # pipe forward
(|*>) => # multi-arg pipe forward
(|**>) => # keyword arg pipe forward
(<|) => # pipe backward
(<*|) => # multi-arg pipe backward
(<**|) => # keyword arg pipe backward
(|?>) => # None-aware pipe forward
(|?*>) => # None-aware multi-arg pipe forward
(|?**>) => # None-aware keyword arg pipe forward
(<?|) => # None-aware pipe backward
(<*?|) => # None-aware multi-arg pipe backward
(<**?|) => # None-aware keyword arg pipe backward
(..), (<..) => # backward function composition
(..>) => # forward function composition
(<*..) => # multi-arg backward function composition
(..*>) => # multi-arg forward function composition
(<**..) => # keyword arg backward function composition
(..**>) => # keyword arg forward function composition
(not) => (operator.not_)
(and) => # boolean and
(or) => # boolean or
(is) => (operator.is_)
(is not) => (operator.is_not)
(in) => (operator.contains)
(not in) => # negative containment
(assert) => def (cond, msg=None) => assert cond, msg # (but a better msg if msg is None)
(raise) => def (exc=None, from_exc=None) => raise exc from from_exc # or just raise if exc is None
# operator functions for multidimensional array concatenation use brackets:
[;] => def (x, y) => [x; y]
[;;] => def (x, y) => [x;; y]
... # and so on for any number of semicolons
# there are two operator functions that don't require parentheses:
.[] => (operator.getitem)
.$[] => # iterator slicing operator
```
関数適用のための演算子関数については、[
`call`
](
演算子関数は利用できませんが、
`await`
同等の構文は[パイプ](
`awaitable |> await`
.
**ココナッツ:**
```coconut
(range(0, 5), range(5, 10)) |*> map$(+) |> list |> print
```
**Python:**
```coconut_python
import operator
print(list(map(operator.add, range(0, 5), range(5, 10))))
```
Coconut は、一般的な部分適用の使用例に対して、さまざまな構文エイリアスをサポートしています。これらは次のとおりです。
```coconut
# attribute access and method calling
.attr1.attr2 => operator.attrgetter("attr1.attr2")
.method(args) => operator.methodcaller("method", args)
.attr.method(args) => .attr ..> .method(args)
# indexing
.[a:b:c] => operator.itemgetter(slice(a, b, c))
.[x][y] => .[x] ..> .[y]
.method[x] => .method ..> .[x]
seq[] => operator.getitem$(seq)
# iterator indexing
.$[a:b:c] => # the equivalent of .[a:b:c] for iterators
.$[x]$[y] => .$[x] ..> .$[y]
iter$[] => # the equivalent of seq[] for iterators
# currying
func$ => ($)$(func)
```
さらに、Coconutの[演算子関数](
```
(. <op> <arg>)
(<arg> <op> .)
```
どこ
`<op>`
は演算子関数であり、
`<arg>`
は任意の式です。演算子関数自体と同様に、このタイプの暗黙的な部分適用には括弧が必要であることに注意してください。この構文は、括弧の代わりに角括弧を使用する多次元配列連結演算子関数では若干異なります。
さらに、Coconut は任意の関数の暗黙的な演算子関数部分もサポートしています。
```
(. `<name>` <arg>)
(<arg> `<name>` .)
```
Coconutの[中置記法](
`<name>`
関数の名前です。さらに、
``
`<name>`
``
代わりに [カスタム演算子](
_非推奨: Coconut では次のものもサポートされています
`obj.`
暗黙の部分として
`getattr$(obj)`
ですが、その使用は非推奨であり、切り替えるよう警告が表示されます。
`getattr$(obj)`
代わりに。_
**ココナッツ:**
```coconut
1 |> "123"[]
mod$ <| 5 <| 3
3 |> (.*2) |> (.+1)
```
**Python:**
```coconut_python
"123"[1]
mod(5, 3)
(3 * 2) + 1
```
Coconut 構文は最新の Python 3 構文のスーパーセットであるため、[Python 3 関数型注釈構文](https://www.python.org/dev/peps/pep-0484/) と [Python 3.6 変数型注釈構文](https://www.python.org/dev/peps/pep-0526/) をサポートしています。デフォルトでは、Coconut はすべての型注釈を Python 2 互換の型コメントにコンパイルします。代わりに型注釈を保持したい場合は、
`--target`
それらをサポートするもの。
サポートされているすべての Python バージョンが [
`typing`
](https://docs.python.org/3/library/typing.html) モジュールでは、Coconut は [
`TYPE_CHECKING`
](
`typing`
輸入と
`TypeVar`
実行時に定義が実行されないようにします。Coconutは[
`typing_extensions`
](https://pypi.org/project/typing-extensions/) 以上
`typing`
実行時にオブジェクトをインポートするときに
`typing`
、現在のPythonバージョンでネイティブにサポートされていない場合でも(これは、
`import typing`
その後
`typing.<Object>`
)。
さらに、[PEP 563](https://www.python.org/dev/peps/pep-0563/) をサポートしていない Python 3 バージョンに型注釈をコンパイルする場合、Coconut は注釈を文字列でラップして、実行時に評価されないようにします (これを回避するには、たとえば実行時に注釈を使用する場合、
`--no-wrap-types`
PEP 563サポートを含むすべてのラッピングを無効にします。
`--target 3.13`
する
`--no-wrap-types`
代わりに [PEP 649](https://peps.python.org/pep-0649/) サポートが使用されるため、何も行いません。
さらに、Coconut は、型注釈をより簡単かつシンプルに記述するための特別な構文を追加します。型注釈の内部では、Coconut は特定の構文構造を異なる方法で処理し、通常表現されるものではなく型注釈にコンパイルします。具体的には、Coconut は次の変換を適用します。
```coconut
A | B
=> typing.Union[A, B]
(A; B)
=> typing.Tuple[A, B]
A?
=> typing.Optional[A]
A[]
=> typing.Sequence[A]
A$[]
=> typing.Iterable[A]
() -> <ret>
=> typing.Callable[[], <ret>]
<arg> -> <ret>
=> typing.Callable[[<arg>], <ret>]
(<args>) -> <ret>
=> typing.Callable[[<args>], <ret>]
-> <ret>
=> typing.Callable[..., <ret>]
(<args>, **<ParamSpec>) -> <ret>
=> typing.Callable[typing.Concatenate[<args>, <ParamSpec>], <ret>]
async (<args>) -> <ret>
=> typing.Callable[[<args>], typing.Awaitable[<ret>]]
```
どこ
`typing`
Python 3.5の組み込み[
`typing`
モジュール](https://docs.python.org/3/library/typing.html)。Callable 構文の詳細については、[PEP 677](https://peps.python.org/pep-0677) を参照してください。これは Coconut で完全にサポートされています。
さらに、Coconut の [演算子関数](
`Protocol`
型注釈内では、代わりに s](https://docs.python.org/3/library/typing.html
_注: への変換は
`Union`
Python 3.10 ではネイティブの [PEP 604](https://www.python.org/dev/peps/pep-0604) サポートがあるため、この変換は Python 3.10 では実行されません。_
これらの変換を [type alias](https://peps.python.org/pep-0484/
```
type <name> = <type>
```
これにより
`<type>`
Coconutの特別な型注釈構文と型を含める
`<name>`
[として
`typing.TypeAlias`
](https://docs.python.org/3/library/typing.html
`<name> = <type>`
型エイリアスの場合、Coconut は型エイリアスを試みていることを認識できず、上記の変換を適用しません。
このような型エイリアス ステートメントは、すべて
`class`
、
`data`
、およびCoconutの関数定義は、Coconutの[型パラメータ構文](
`type OrStr[T] = T | str`
.
Coconut の [operator function](
`Protocol`
](https://docs.python.org/3/library/typing.html
`Protocol`
すべて利用可能
`Protocol`
以下にリストします。
演算子関数の場合
```
(+)
(*)
(**)
(/)
(//)
(%)
(&)
(^)
(|)
(<<)
(>>)
(@)
```
結果として
`Protocol`
は
```coconut
class SupportsOp[T, U, V](Protocol):
def __op__(self: T, other: U) -> V:
raise NotImplementedError(...)
```
どこ
`__op__`
は、その演算子に対応するマジックメソッドです。
演算子関数の場合
`(-)`
、結果として
`Protocol`
は:
```coconut
class SupportsMinus[T, U, V](Protocol):
def __sub__(self: T, other: U) -> V:
raise NotImplementedError
def __neg__(self: T) -> V:
raise NotImplementedError
```
演算子関数の場合
`(~)`
、結果として
`Protocol`
は:
```coconut
class SupportsInv[T, V](Protocol):
def __invert__(self: T) -> V:
raise NotImplementedError(...)
```
`List`
対
`Sequence`
重要なのは、
`T[]`
にマッピングされない
`typing.List[T]`
しかし、
`typing.Sequence[T]`
これにより、結果の型は共変となり、
`U`
のサブタイプである
`T`
、 それから
`U[]`
のサブタイプである
`T[]`
さらに、
`Sequence[T]`
タプルを許容し、慣用的な関数型スタイルで書く場合、代入はまれで、タプルは一般的であるべきです。
`Sequence`
両方のケースをカバーし、タプルとリストに対応し、インデックス付きの代入を防止します。
`Sequence`
、MyPy はエラーを生成します:
```coconut
foo: int[] = [0, 1, 2, 3, 4, 5]
foo[0] = 1 # MyPy error: "Unsupported target for indexed assignment"
```
使用したい場合
`List`
代わりに (たとえば、インデックス割り当てをサポートする場合)、標準の Python 3.5 変数型アノテーション構文を使用します。
`foo: List[<type>]`
.
_注: 定義したタイプを簡単に表示するには、[
`reveal_type`
そして
`reveal_locals`
](
**ココナッツ:**
```coconut
def int_map(
f: int -> int,
xs: int[],
) -> int[] =
xs |> map$(f) |> list
type CanAddAndSub = (+) &: (-)
```
**Python:**
```coconut_python
import typing # unlike this typing import, Coconut produces universal code
def int_map(
f, # type: typing.Callable[[int], int]
xs, # type: typing.Sequence[int]
):
# type: (...) -> typing.Sequence[int]
return list(map(f, xs))
T = typing.TypeVar("T", infer_variance=True)
U = typing.TypeVar("U", infer_variance=True)
V = typing.TypeVar("V", infer_variance=True)
class CanAddAndSub(typing.Protocol, typing.Generic[T, U, V]):
def __add__(self: T, other: U) -> V:
raise NotImplementedError
def __sub__(self: T, other: U) -> V:
raise NotImplementedError
def __neg__(self: T) -> V:
raise NotImplementedError
```
Coconut は、多次元配列リテラルと配列 [連結](https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html)/[スタック](https://numpy.org/doc/stable/reference/generated/numpy.stack.html) 構文をサポートしています。
デフォルトでは、すべての多次元配列構文は、Python のリストのリスト (または任意の非リスト) に対してのみ機能します。
`str`
`Sequence`
)。ただし、[
`numpy`
](
`numpy`
代わりに呼び出しが行われます。カスタムオブジェクトに多次元配列の連結サポートを与えるには、次のように定義します。
`type(obj).__matconcat__`
(次のように動作するはずです
`np.concat`
)、
`obj.ndim`
(次のように動作するはずです
`np.ndarray.ndim`
)、 そして
`obj.reshape`
(次のように動作するはずです
`np.ndarray.reshape`
)。
簡単な例として、2D 行列は行を次のように区切ることで構築できます。
`;;`
リストリテラル内:
```coconut_pycon
>>> [1, 2 ;;
3, 4]
[[1, 2], [3, 4]]
>>> import numpy as np
>>> np.array([1, 2 ;; 3, 4])
array([[1, 2],
[3, 4]])
```
ご覧のとおり、
`np.array`
(または同等のもの)を使用して、結果のリストを実際の配列に変換することができます。この構文は、
`;;`
リストリテラル内では、連結/スタックとして機能します。
`-2`
軸(内側の配列は
`(1, 2)`
連結前の配列)。この連結はここではPythonのリストのリストで完全に行われていることに注意してください。
`np.array`
呼び出しは最後にのみ行われます。
一般的に、セミコロンの数は、連結する末尾からの次元を示します。つまり、
`;`
は、
`-1`
軸、
`;;`
に沿って
`-2`
軸など。連結前に、配列は常に連結を可能にするのに十分な大きさのシェイプにブロードキャストされます。
したがって、
`a`
は
`numpy`
配列、
`[a; a]`
は以下と同等である
`np.concatenate((a, a), axis=-1)`
、 その間
`[a ;; a]`
のバージョンに相当する
`np.concatenate((a, a), axis=-2)`
それはまた、
`a`
少なくとも2次元である。通常のリストのリストの場合、動作は同じだが、
`numpy`
呼び出します。
複数の異なる連結演算子を使用する場合、セミコロンの数が最も少ない演算子が最も密接に結合されます。したがって、3D 配列リテラルは次のように記述できます。
```coconut_pycon
>>> [1, 2 ;;
3, 4
;;;
5, 6 ;;
7, 8]
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
```
_注: 多次元配列の連結のための[演算子関数](
`[;]`
、
`[;;]`
など(括弧はいくつでも使えます)。[暗黙の部分適用](
`[. ; x]`
、
`[x ; .]`
など_
Coconut の多次元配列構文は [Julia](https://docs.julialang.org/en/v1/manual/arrays/
`numpy`
)ですが、Juliaでは列優先です。つまり、
`;`
Juliaでは垂直連結ですが、Coconutでは**水平連結**であり、
`;;`
Julia では水平連結ですが、Coconut では **垂直連結** です。
**Coconut:**
```coconut_pycon
>>> [[1;;2] ; [3;;4]]
[[1, 3], [2, 4]]
```
_配列リテラルは、列が最初に垂直連結によって作成される場合、列優先で記述できます(
`;;`
)を水平連結(
`;`
)。
```coconut_pycon
>>> [range(3) |> list ;; x+1 for x in range(3)]
[[0, 1, 2], [1, 2, 3]]
```
_多次元配列リテラルでは、内包表記を含む任意の式が許可されます。_
```coconut_pycon
>>> import numpy as np
>>> a = np.array([1, 2 ;; 3, 4])
>>> [a ; a]
array([[1, 2, 1, 2],
[3, 4, 3, 4]])
>>> [a ;; a]
array([[1, 2],
[3, 4],
[1, 2],
[3, 4]])
>>> [a ;;; a]
array([[[1, 2],
[3, 4]],
[[1, 2],
[3, 4]]])
```
_さまざまな連結演算子がどのように機能するかの一般的な説明
`numpy`
配列。_
**Python:** _同等の Python 配列リテラルは、各例の印刷された表現で確認できます。_
Coconut は遅延リストの作成をサポートしています。遅延リストでは、リストの内容は反復子として扱われ、必要になるまで評価されません。ただし、通常の反復子とは異なり、遅延リストは複数回反復されても同じ結果が返されます。遅延リストは、コンマで区切られた項目のリストを
`(|`
そして
`|)`
(いわゆる「バナナ括弧」)の代わりに
`[`
そして
`]`
リストまたは
`(`
そして
`)`
タプルの場合。
遅延リストは、内部で [reiterable](
遅延リストでは、シーケンスはコンテンツが要求されたときにのみ評価され、関数型プログラミングの主力であり、リストのコンテンツの動的な評価を可能にします。
**Coconut:**
```coconut
(| print("hello,"), print("world!") |) |> consume
```
**Python:**
_遅延リストの代わりに複雑なイテレータ理解なしでは実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
Coconut は、次の形式の暗黙的な関数適用をサポートしています。
`f x y`
、これは次のようにコンパイルされます
`f(x, y)`
(注:**そうではありません**
`f(x)(y)`
これは自動カリー化を行う多くの言語で一般的です。
さらに、最初の引数が呼び出し可能ではなく、代わりに
`int`
、
`float`
、
`complex`
、 または [
`numpy`
](
`2 x`
は以下と同等である
`2*x`
.
最初の項目は任意のアトムにすることができますが、後続の引数は厳しく制限されており、次のものである必要があります:
- 変数/属性 (例:
`a.b`
)、
- リテラル定数(例:
`True`
)、
- 数値リテラル(例:
`1.5`
) (2 進数、16 進数、8 進数は不可)、または
- 上記のいずれかに指数が続く (例:
`a**-5`
)。
例えば、
`(f .. g) x 1`
動作しますが、
`f x [1]`
、
`f x (1+2)`
、 そして
`f "abc"`
しません。
暗黙的な関数適用と係数構文は、単純な使用例のみを対象としています。より複雑なケースでは、標準の乗算演算子を使用してください。
`*`
、標準関数適用、または[パイプ](
暗黙的な関数適用と係数構文は、
`**`
しかし単項演算子よりも優先順位が高い。その結果、
`2 x**2 + 3 x`
は以下と同等である
`2 * x**2 + 3 * x`
.
混乱を招く可能性があるため、暗黙的な関数適用と係数構文では、一部の構文構造が明示的に禁止されています。具体的には、次のとおりです。
- 文字列は、[Python の暗黙的な文字列連結](https://stackoverflow.com/questions/18842779/string-concatenation-without-operator) と競合するため、暗黙的な関数適用/係数構文のどこでも常に禁止されています。
- 暗黙的な係数構文で 2 つ以上の数値リテラルを乗算することは禁止されているため、
`10 20`
許可されません。
-
`await`
暗黙の関数適用や係数構文の前では使用できない。
`await`
次のように、式を括弧で囲むだけです。
`await (f x)`
.
_注: 暗黙的な関数の適用と係数の構文は、[Coconut を
`xonsh`
](
**Coconut:**
```coconut
def f(x, y) = (x, y)
print(f 5 10)
```
```coconut
def p1(x) = x + 1
print <| p1 5
```
```coconut
quad = 5 x**2 + 3 x + 1
```
**Python:**
```coconut_python
def f(x, y): return (x, y)
print(f(100, 5+6))
```
```coconut_python
def p1(x): return x + 1
print(p1(5))
```
```coconut_python
quad = 5 * x**2 + 3 * x + 1
```
長い変数名を同じ名前のキーワード引数として渡す場合、Coconut は次の構文をサポートします。
```
f(long_variable_name=)
```
略語として
```
f(long_variable_name=long_variable_name)
```
このような構文は、[部分適用](
`namedtuple`
s](
`class`
/
`data`
/匿名
`namedtuple`
パターン](
_非推奨: Coconut は
`f(...=long_variable_name)`
代替の省略構文として。_
**Coconut:**
```coconut
really_long_variable_name_1 = get_1()
really_long_variable_name_2 = get_2()
main_func(
really_long_variable_name_1=,
really_long_variable_name_2=,
)
```
**Python:**
```coconut_python
really_long_variable_name_1 = get_1()
really_long_variable_name_2 = get_2()
main_func(
really_long_variable_name_1=really_long_variable_name_1,
really_long_variable_name_2=really_long_variable_name_2,
)
```
Coconut は匿名 [ をサポートします
`namedtuple`
](https://docs.python.org/3/library/collections.html
`(a=1, b=2)`
同じように使用できます
`(1, 2)`
ただし名前が追加されています。匿名
`namedtuple`
は常にpickle化可能であり、[
`__match_args__`
](https://peps.python.org/pep-0622/) をすべての Python バージョンで使用できます。
匿名 namedtuple リテラルの構文は次のとおりです。
```coconut
(<name> [: <type>] = <value>, ...)
```
ここで、もし
`<type>`
は任意のフィールドに対して与えられ、[
`typing.NamedTuple`
](https://docs.python.org/3/library/typing.html
`collections.namedtuple`
。
匿名
`namedtuple`
s は [キーワード引数名の省略](
`_namedtuple_of`
Pythonのバージョンについて
`>=3.6`
、
`_namedtuple_of`
匿名の名前付きタプルリテラルの動作を模倣できる組み込み関数として提供されており、
`_namedtuple_of(a=1, b=2)`
は以下と同等である
`(a=1, b=2)`
。 以来
`_namedtuple_of`
Python 3.6 以降でのみ使用できますが、匿名の名前付きタプル リテラルはどの Python バージョンでも機能するため、代わりに匿名の名前付きタプル リテラルを使用することをお勧めします。
_
`_namedtuple_of`
名前付きタプル リテラルに、それらを再作成するために使用できる式に対応する表現を与えるために提供されています。_
**Coconut:**
```coconut
users = [
(id=1, name="Alice"),
(id=2, name="Bob"),
]
```
**Python:**
```coconut_python
from collections import namedtuple
users = [
namedtuple("_", "id, name")(1, "Alice"),
namedtuple("_", "id, name")(2, "Bob"),
]
```
Coconut ではオプションとして
`s`
Python のセットリテラルの前に追加されます。ほとんどの場合、これは何もしませんが、空のセットの場合は、Coconut にそれが空のセットであり、空の辞書ではないことを知らせます。セットリテラルは、アンパック構文もサポートしています (例:
`s{*xs}`
)。
さらに、Coconut は
`s`
と
`f`
生成する
`frozenset`
または
`m`
ココナッツを生成するには[
`multiset`
](
**ココナッツ:**
```coconut
empty_frozen_set = f{}
```
**Python:**
```coconut_python
empty_frozen_set = frozenset()
```
Python の
`<num>j`
または
`<num>J`
虚数リテラルの表記法に加えて、Coconutは
`<num>i`
または
`<num>I`
、数学的なコンテキストで使用される場合に虚数リテラルを読みやすくします。
虚数リテラルは、次の語彙定義によって記述されます。
```coconut
imagnumber ::= (floatnumber | intpart) ("j" | "J" | "i" | "I")
```
虚数リテラルは、実部が 0.0 の複素数を生成します。複素数は浮動小数点数のペアとして表され、その範囲には同じ制限があります。実部が 0 でない複素数を作成するには、それに浮動小数点数を加算します。例:
`(3+4i)`
架空のリテラルの例:
```coconut
3.14i 10.i 10i .001i 1e100i 3.14e-10i
```
**ココナッツ:**
```coconut
3 + 4i |> abs |> print
```
**Python:**
```coconut_python
print(abs(3 + 4j))
```
Python は三項演算子構文をサポートしています
```coconut_python
result = if_true if condition else if_false
```
Coconut は Python のスーパーセットなので、Coconut もこれをサポートしています。
ただし、Coconut は、より一般的な引数の順序を使用する代替構文も提供しています。
```
result = if condition then if_true else if_false
```
ココナッツ特有の
`then`
キーワード([Coconutでは
`then`
変数名として](
**ココナッツ:**
```coconut
value = (
if should_use_a() then a
else if should_use_b() then b
else if should_use_c() then c
else fallback
)
```
**Python:**
```coconut_python
value = (
a if should_use_a() else
b if should_use_b() else
c if should_use_c() else
fallback
)
```
```{contents}
---
local:
depth: 1
---
```
Coconut は、次の条件を満たす関数に対して、自動 [末尾呼び出し](https://en.wikipedia.org/wiki/Tail_call) 最適化と末尾再帰の除去を実行します:
1. 直接返す必要があります (次のいずれかを使用)
`return`
または[代入関数記法](
2. ジェネレーターであってはならない (
`yield`
)または非同期関数(
`async`
)。
末尾呼び出し最適化 (末尾再帰の除去ではない) は、1) 相互再帰と 2) [ を使用して複数の定義に分割されたパターン マッチング関数でも機能します。
`addpattern`
](
**ココナッツ:**
```coconut
# unlike in Python, this function will never hit a maximum recursion depth error
def factorial(n, acc=1):
match n:
case 0:
return acc
case int() if n > 0:
return factorial(n-1, acc*n)
```
_末尾再帰の除去を紹介します。_
```coconut
# unlike in Python, neither of these functions will ever hit a maximum recursion depth error
def is_even(0) = True
addpattern def is_even(n `isinstance` int if n > 0) = is_odd(n-1)
def is_odd(0) = False
addpattern def is_odd(n `isinstance` int if n > 0) = is_even(n-1)
```
_末尾呼び出しの最適化を紹介します。_
**Python:**
_関数を書き直さないと実行できません。_
`--no-tco`
フラグ
末尾呼び出し最適化は、
`--no-tco`
コマンドライン オプション。トレースバックの読み取りに問題がある場合や、最大のパフォーマンスが必要な場合に役立ちます。
`--no-tco`
末尾再帰の除去は無効になりません。
これは、末尾再帰の除去は通常何もしないよりも高速ですが、他の種類の末尾呼び出しの最適化は通常何もしないよりも低速であるためです。
末尾再帰の除去は、Python の関数呼び出しのオーバーヘッドがかなり大きいため、パフォーマンスを大幅に向上させます。再帰関数を巻き戻すことで、はるかに少ない関数呼び出しを実行する必要があります。
`--no-tco`
フラグが無効になっている場合、Coconutは非再帰末尾呼び出し、分割パターンマッチング関数、相互再帰、末尾再帰を処理するすべてのタイプの末尾呼び出し最適化を試みます。
`--no-tco`
フラグが有効になっている場合、Coconut は末尾再帰の除去以外の末尾呼び出しの最適化を実行しません。
Coconut は、ラムダまたは内部関数を使用する関数で末尾再帰の除去を実行しません。これは、Python がラムダを処理する方法によるものです。
各ラムダは、名前空間のコピーではなく、それを囲む名前空間へのポインターを格納します。したがって、Coconut コンパイラがラムダを生成した名前空間内の何かをリサイクルしようとすると (これは TRE で実行する必要があります)、ラムダは遡及的に変更できます。
Python でこの動作を示す簡単な例:
```python
x = 1
foo = lambda: x
print(foo()) # 1
x = 2 # Directly alter the values in the namespace enclosing foo
print(foo()) # 2 (!)
```
これは意図しない、潜在的に有害な結果をもたらす可能性があるため、Coconut はラムダまたは内部関数を持つ関数に対しては TRE を実行しないことを選択します。
Coconut では、関数本体の最後の行を自動的に返す代入関数の定義が可能です。代入関数は、次の代入によって構築されます。
`=`
のために
`:`
関数定義行の後に記述します。したがって、代入関数定義の構文は、
```coconut
[async] def <name>(<args>) = <expr>
```
ワンライナーや
```coconut
[async] def <name>(<args>) =
<stmts>
<expr>
```
完全な機能については、
`<name>`
関数の名前です。
`<args>`
関数の引数は、
`<stmts>`
関数が実行すべきステートメントであり、
`<expr>`
関数が返す値です。
_注: 代入関数定義は、インフィックスおよび/またはパターン マッチング関数定義と組み合わせることができます。_
Coconut の代入関数定義は、ラムダへの代入と同じくらい簡単に記述できますが、通常の Python 関数定義にコンパイルされるため、トレースバックに名前付きで表示されます。
**Coconut:**
```coconut
def binexp(x) = 2**x
5 |> binexp |> print
```
**Python:**
```coconut_python
def binexp(x): return 2**x
print(binexp(5))
```
Coconut パターンマッチング関数は、引数が割り当てる変数ではなく、照合するパターンである点を除けば、通常の関数と同じです。パターンマッチング関数定義の構文は次のとおりです。
```coconut
[match] def <name>(<arg>, <arg>, ... [if <cond>]) [-> <return_type>]:
<body>
```
どこ
`<arg>`
は次のように定義される
```coconut
[*|**] <pattern> [= <default>]
```
どこ
`<name>`
関数の名前です。
`<cond>`
オプションの追加チェックです。
`<body>`
関数の本体であり、
`<pattern>`
ココナッツの[
`match`
ステートメント](
`<default>`
引数が渡されない場合のオプションのデフォルトであり、
`<return_type>`
はオプションの戻り値の型注釈です(引数の型注釈はパターンマッチング関数ではサポートされていないことに注意してください)。
`match`
先頭のキーワードはオプションですが、パターンマッチング関数の定義と通常の関数の定義を区別するために必要になる場合があります。これは、Python関数の定義が常に優先されるためです。
`async`
そして
`match`
キーワードは任意の順序で指定できます。
`<pattern>`
変数名を持ちます (パターン全体をバインドする任意の変数バインディングを介して、例:
`x`
で
`int(x)`
または
`[a, b] as x`
) の場合、結果として得られるパターン マッチング関数は、その変数名を使用したキーワード引数をサポートします。
引数でのパターン マッチングのサポートに加えて、パターン マッチング関数定義には、Python 関数と比較していくつかの注目すべき違いもあります。具体的には、次のようになります。
- パターン マッチング関数定義が失敗すると、[
`MatchError`
](
`TypeError`
.
- パターンマッチング関数定義のすべてのデフォルトは、早期バインドではなく遅延バインドです。したがって、
`match def f(xs=[]) = xs`
呼び出しごとに新しいリストをインスタンス化します。
`xs`
とは異なり、与えられていない
`def f(xs=[]) = xs`
、すべての呼び出しに同じリストを使用します。
`xs`
は指定されていません。これにより、後の引数のデフォルトを、前の引数の一致した値で指定することもできます。
`match def f(x, y=x) = (x, y)`
.
パターンマッチング関数の定義は、
`async`
機能、[
`copyclosure`
関数](
`yield`
関数](
`def`
任意の順序で配置できます。
**ココナッツ:**
```coconut
def last_two(_ + [a, b]):
return a, b
def xydict_to_xytuple({"x": x `isinstance` int, "y": y `isinstance` int}):
return x, y
range(5) |> last_two |> print
{"x":1, "y":2} |> xydict_to_xytuple |> print
```
**Python:**
_関数の先頭で長い一連のチェックを行わないと実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
`case`
関数
さまざまなケースでパターンマッチング関数を簡単に定義するために、Coconut は
`case def`
ココナッツの[
`case`
](
```
case def <name>:
case(<arg>, <arg>, ... [if <cond>]):
<body>
case(<arg>, <arg>, ... [if <cond>]):
<body>
...
```
それぞれのパターンは
`case`
一致するものが見つかるまで順番にチェックされ、その一致の下の本体が実行される、または[
`MatchError`
](
`case(...)`
ステートメントは、あたかもそれぞれが別々に定義され、[と組み合わされたかのように、独立してチェックされる別のパターンマッチング関数シグネチャとして効果的に扱われます。
`addpattern`
](
個々のボディは、[代入関数構文](
```
case def <name>:
case(<arg>, <arg>, ... [if <cond>]) = <body>
```
は以下と同等である
```
case def <name>:
case(<arg>, <arg>, ... [if <cond>]): return <body>
```
`case`
関数定義は、
`async`
機能、[
`copyclosure`
関数](
`yield`
関数](
`def`
任意の順序で配置できます。
`case def`
パターンマッチング関数の型注釈を簡単に提供することもできます。型注釈を追加するには、
`case def`
、単に
`case(...)`
声明には、いくつかの
`type(...)`
ステートメントも同様にコンパイルされ、[
`typing.overload`
](https://docs.python.org/3/library/typing.html
```
case def <name>[<type vars>]:
type(<arg>: <type>, <arg>: <type>, ...) -> <type>
type(<arg>: <type>, <arg>: <type>, ...) -> <type>
...
```
これに、
`case(...)`
ステートメント。
**ココナッツ:**
```coconut
case def my_min[T]:
type(x: T, y: T) -> T
case(x, y if x <= y) = x
case(x, y) = y
type(xs: T[]) -> T
case([x]) = x
case([x] + xs) = my_min(x, my_min(xs))
```
**Python:**
_パターンマッチングごとに長い一連のチェックを行わないと実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
`addpattern`
機能
ココナッツは
`addpattern def`
完全な構文のショートカットとして
```coconut
@addpattern(func)
match def func(...):
...
```
[ を使用した構文
`addpattern`
](
デコレータを
`addpattern def`
関数の場合は、必ず _最後の_ パターン関数に配置してください。
複雑なマルチパターン関数の場合は、通常、[
`case def`
](
`addpattern def`
ほとんどの場合。
_非推奨:
`addpattern def`
通常の[
`match def`
](
`CoconutWarning`
](
**Coconut:**
```coconut
addpattern def factorial(0) = 1
addpattern def factorial(n) = n * factorial(n - 1)
```
**Python:**
_複雑なデコレータ定義と、各パターン マッチングの長い一連のチェックなしでは実行できません。Python 構文については、コンパイルされたコードを参照してください。_
`copyclosure`
関数
Coconut は次の構文をサポートしています
```
copyclosure def <name>(<args>):
<body>
```
関数が定義された時点でのその関数の囲みスコープの浅いコピーをクロージャとして使用する関数を定義します。通常の Python 関数の場合のように、それらのスコープへの参照を使用するわけではありません。
たとえば、
関数が定義された時点でのその関数の囲みスコープの浅いコピーをクロージャとして使用する関数を定義します。通常の Python 関数の場合のように、それらのスコープへの参照を使用するのではなく。
たとえば、`in
```coconut
def outer_func():
funcs = []
for x in range(10):
copyclosure def inner_func():
return x
funcs.append(inner_func)
return funcs
```
結果として
`inner_func`
それぞれ異なる
`x`
すべて同じではなく価値がある
`x`
価値を見出すのは
`x`
関数の実行時ではなく、関数の定義時にバインドされました。
`copyclosure`
関数は、
`async`
機能、[
`yield`
関数](#explicit-generators)、[パターンマッチング関数](#pattern-matching-functions)、[中置関数定義](#infix-functions)、[代入関数構文](#assignment-functions)。
`def`
任意の順序で配置できます。
`global`
または
`nonlocal`
は、
`copyclosure`
関数では、囲んでいるスコープ内の変数を変更することはできません。ただし、関数を複数回呼び出しても状態は保持されます。
`copyclosure`
関数。
##### 例
**ココナッツ:**
```coconut
def outer_func():
funcs = []
for x in range(10):
copyclosure def inner_func():
return x
funcs.append(inner_func)
return funcs
```
**Python:**
```coconut_python
from functools import partial
def outer_func():
funcs = []
for x in range(10):
def inner_func(_x):
return _x
funcs.append(partial(inner_func, x))
return funcs
```
### 明示的なジェネレータ
Coconut は次の構文をサポートしています
```
yield def <name>(<args>):
<body>
```
ジェネレータ関数を明示的に定義していることを示すために使用します。これは、
`yield`
関数内の が削除されると、常にジェネレータ関数になります。
明示的なジェネレータ関数は、
`async`
機能、[
`copyclosure`
関数](#copyclosure-functions)、[パターンマッチング関数](#pattern-matching-functions)、[中置関数定義](#infix-functions)、[代入関数構文](#assignment-functions) (ただし、ここでの代入関数構文はジェネレータの戻り値を作成することに注意してください)。
`def`
任意の順序で配置できます。
##### 例
**ココナッツ:**
```coconut
yield def empty_it(): pass
```
**Python:**
```coconut_python
def empty_it():
if False:
yield
```
### ドット付き関数定義
Coconut では、[PEP 542](https://www.python.org/dev/peps/pep-0542/) で指定されているように、ドット付きの名前を使用して関数を定義し、関数をオブジェクトのメソッドとして割り当てることができます。ドット付き関数定義は、上記の他のすべてのタイプの関数定義と組み合わせることができます。
##### 例
**Coconut:**
```coconut
def MyClass.my_method(self):
...
```
**Python:**
```coconut_python
def my_method(self):
...
MyClass.my_method = my_method
```
## ステートメント
```{contents}
---
local:
depth: 1
---
```
### 分割代入
Coconut は大幅に強化された分割代入をサポートしています。これは Python のタプル/リスト分割代入に似ていますが、はるかに強力です。Coconut の分割代入の構文は次のとおりです。
```coconut
[match] <pattern> = <value>
```
どこ
`<value>`
任意の表現であり、
`<pattern>`
ココナッツの[
`match`
ステートメント](#match)。
`match`
先頭のキーワードはオプションですが、常に優先される通常の代入と構造化代入を区別するために必要な場合があります。Coconut の構造化代入は、次の構文に従う match ステートメントと同等です。
```coconut
match <pattern> in <value>:
pass
else:
err = MatchError(<error message>)
err.pattern = "<pattern>"
err.value = <value>
raise err
```
分割代入文が失敗した場合、
`match`
ブロックが失敗した場合、[
`MatchError`
失敗を説明する](#matcherror)オブジェクトが生成されます。
##### 例
**Coconut:**
```coconut
_ + [a, b] = [0, 1, 2, 3]
print(a, b)
```
**Python:**
_分割代入文の代わりに長い一連のチェックを行わないと実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
### 型パラメータ構文
Coconut は、すべての Python バージョンで [Python 3.12 PEP 695](https://peps.python.org/pep-0695/) 型パラメータ構文を完全にサポートしています。
これには、クラスの型パラメータ、[
`data`
型](#data)、および[すべてのタイプの関数定義](#function-definition)。さまざまなタイプの関数定義では、型パラメータは常に関数名の直後の括弧で囲まれます。Coconut の [拡張型注釈構文](#enhanced-type-annotation) は、すべての型パラメータ境界でサポートされています。
_警告:
`mypy`
サポートを追加
`infer_variance=True`
で
`TypeVar`
、
`TypeVar`
このようにして作成された境界は常に不変です。_
さらに、Coconut は代替境界構文をサポートしています。
`type NewType[T <: bound] = ...`
それよりも
`type NewType[T: bound] = ...`
型ではなく上限であることをより明確にするために、
`--strict`
モード、
`<:`
必要となる
`:`
すべての型パラメータ境界に対して。_非推奨:
`<=`
代替として使うこともできる
`<:`
._
注意:
`<:`
構文は[型境界](https://peps.python.org/pep-0695/#upper-bound-specification)にのみ使用し、[型制約](https://peps.python.org/pep-0695/#constrained-type-specification)には使用しないでください。型制約の場合、CoconutスタイルではバニラPythonが推奨されます。
`:`
構文は、機能的に異なるものの、一見して区別がつきにくい2つのケースを区別するのに役立ちます。これは、
`--strict`
モード。
_デフォルトでは、前方参照を有効にして実行時のパフォーマンスを向上させるために、すべての型宣言が文字列でラップされることに注意してください。実行時に型注釈を使用したい場合など、これを望まない場合は、
`--no-wrap-types`
flag._
##### PEP 695 ドキュメント
この PEP より前のジェネリック クラスの定義は次のようになります。
```coconut_python
from typing import Generic, TypeVar
_T_co = TypeVar("_T_co", covariant=True, bound=str)
class ClassA(Generic[_T_co]):
def method1(self) -> _T_co:
...
```
新しい構文では、次のようになります。
```coconut
class ClassA[T: str]:
def method1(self) -> T:
...
```
今日はジェネリック関数の例を紹介します。
```coconut_python
from typing import TypeVar
_T = TypeVar("_T")
def func(a: _T, b: _T) -> _T:
...
```
そして新しい構文。
```coconut
def func[T](a: T, b: T) -> T:
...
```
以下は、ジェネリック型エイリアスの例です。
```coconut_python
from typing import TypeAlias
_T = TypeVar("_T")
ListOrSet: TypeAlias = list[_T] | set[_T]
```
そして新しい構文です。
```coconut
type ListOrSet[T] = list[T] | set[T]
```
##### 例
**ココナッツ:**
```coconut
data D[T](x: T, y: T)
def my_ident[T](x: T) -> T = x
```
**Python:**
_データ型の複雑な定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
### 暗黙的
`pass`
ココナッツはシンプルな
`class name(base)`
そして
`data name(args)`
別名として
`class name(base): pass`
そして
`data name(args): pass`
.
##### 例
**ココナッツ:**
```coconut
class Tree
data Empty from Tree
data Leaf(item) from Tree
data Node(left, right) from Tree
```
**Python:**
_各データ型の一連のメソッド定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
### ステートメントのネスト
Coconut は、同じ行での複合ステートメントのネストをサポートしています。これにより、
`match`
そして
`if`
文を一緒にしたり、複合文として
`try`
ステートメント。
##### 例
**ココナッツ:**
```coconut
if invalid(input_list):
raise Exception()
else: match [head] + tail in input_list:
print(head, tail)
else:
print(input_list)
```
**Python:**
```coconut_python
from collections.abc import Sequence
if invalid(input_list):
raise Exception()
elif isinstance(input_list, Sequence) and len(input_list) >= 1:
head, tail = inputlist[0], inputlist[1:]
print(head, tail)
else:
print(input_list)
```
###
`except`
ステートメント
Python 3 では、複数の例外をキャッチする場合、それらを括弧内に配置する必要があり、Python 2 でカンマの代わりに使用されていた例外を括弧で囲むことが禁止されています。
`as`
Coconutでは、Python 3と同様に、except文のカンマを括弧なしで複数の例外をキャッチすることに変換できます。
`as`
例外を名前にバインドするには、常に が必要です。
##### 例
**Coconut:**
```coconut
try:
unsafe_func(arg)
except SyntaxError, ValueError as err:
handle(err)
```
**Python:**
```coconut_python
try:
unsafe_func(arg)
except (SyntaxError, ValueError) as err:
handle(err)
```
### 列をなして
`global`
そして
`nonlocal`
課題
ココナッツは
`global`
または
`nonlocal`
変数のリストへの代入、または変数への(拡張)代入の前に代入を行う
`global`
または
`nonlocal`
それぞれ。
##### 例
**ココナッツ:**
```coconut
global state_a, state_b = 10, 100
global state_c += 1
```
**Python:**
```coconut_python
global state_a, state_b; state_a, state_b = 10, 100
global state_c; state_c += 1
```
### コード パススルー
Coconut は、[Cython](http://cython.org/) や [Mython](http://mython.org/) などの他の Python バリアントとの互換性のために、任意のコードをコンパイラーにそのまま渡す機能をサポートしています。Coconut を使用して別の Python バリアントにコンパイルする場合は、[ソース ファイルに適切な名前を付ける](#ソース ファイルの命名) ことで、コンパイルされた結果のコードが目的の用途に適したファイル拡張子を持つようにしてください。
`\(`
対応する閉じ括弧も通過し、
`\\`
、その下にインデントを許すという追加の効果があります。
##### 例
**Coconut:**
```coconut
\\cdef f(x):
return x |> g
```
**Python:**
```coconut_python
cdef f(x):
return g(x)
```
### 強化された括弧による継続
Coconut 構文は最新の Python 3 構文のスーパーセットであるため、Coconut は Python と同じ行継続構文をサポートしています。つまり、バックスラッシュによる行継続と、括弧、角括弧、中括弧内の暗黙的な行継続の両方が機能します。
ただし、Python では、複数の
`with`
バックスラッシュ継続のみがサポートされ、括弧継続はサポートされていないステートメント)があります。Coconutはこれらすべてのケースで括弧継続をサポートします。これには、[PEP 679](https://peps.python.org/pep-0679)に従って括弧付き継続のサポートも含まれます。
`assert`
ステートメント。
どこでも括弧による継続をサポートすることで、バックスラッシュによる継続を避けて暗黙の括弧による継続を採用する [PEP 8](https://www.python.org/dev/peps/pep-0008/) 規則を常に従うことができます。PEP 8 より:
> 長い行を折り返す推奨方法は、括弧、大括弧、中括弧内で Python の暗黙の行継続を使用することです。長い行は、式を括弧で囲むことで複数行に分割できます。行継続にはバックスラッシュを使用するよりも、これらを使用することをお勧めします。
_注: 渡す
`--strict`
バックスラッシュ継続を禁止することで PEP 8 規則を強制します。_
##### 例
**Coconut:**
```coconut
with (open('/path/to/some/file/you/want/to/read') as file_1,
open('/path/to/some/file/being/written', 'w') as file_2):
file_2.write(file_1.read())
```
**Python:**
```coconut_python
with open('/path/to/some/file/you/want/to/read') as file_1:
with open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
```
### 代入式の連鎖
Python とは異なり、Coconut では代入式を連鎖させることができます。
`a := b := c`
ただし、代入式は一般的に現在、
`--target 3.8`
またはそれ以上。
##### 例
**ココナッツ:**
```coconut
(a := b := 1)
```
**Python:**
```coconut_python
(a := (b := 1))
```
## 組み込み
```{contents}
---
local:
depth: 2
---
```
### 組み込み関数デコレータ
```{contents}
---
local:
depth: 1
---
```
####
`addpattern`
**addpattern**(_base\_func_、*_add\_funcs_、_allow\_any\_func_=
`False`
)
[パターンマッチング関数](#pattern-matching-functions) である引数を 1 つ受け取り、既存の関数のパターンをデコレートする新しい関数に追加するデコレータを返します。最初に既存のパターンがチェックされ、次に新しいパターンがチェックされます。
`addpattern`
新しいパターンを直接渡すことができるショートカット構文もサポートしています。
おおよそ次の構文と同等です:
```coconut_python
def _pattern_adder(base_func, add_func):
def add_pattern_func(*args, **kwargs):
try:
return base_func(*args, **kwargs)
except MatchError:
return add_func(*args, **kwargs)
return add_pattern_func
def addpattern(base_func, *add_funcs, allow_any_func=False):
"""Decorator to add a new case to a pattern-matching function (where the new case is checked last).
Pass allow_any_func=True to allow any object as the base_func rather than just pattern-matching functions.
If add_func is passed, addpattern(base_func, add_func) is equivalent to addpattern(base_func)(add_func).
"""
if not add_funcs:
return addpattern$(base_func)
for add_func in add_funcs:
base_func = pattern_adder(base_func, add_func)
return base_func
```
もしあなたが
`addpattern`
関数のドキュメント文字列を関数の最後の関数に記述してください。
`addpattern`
パターンマッチング関数でなければなりません。
`addpattern`
パターンマッチング関数を受け取った場合、関数は例外を発生しません
`MatchError`
、 そして
`addpattern`
失敗したマッチを検出できません。したがって、後で呼び出される関数があった場合、
`addpattern`
最初の一致が失敗したことを知らず、正しいパスに到達できない。
たとえば、次のコードは
`TypeError`
```coconut
def print_type():
print("Received no arguments.")
@addpattern(print_type)
def print_type(int()):
print("Received an int.")
print_type()
print_type(1)
```
これは、
`match`
キーワード。例:
```coconut
match def print_type():
print("Received no arguments.")
addpattern def print_type(int()):
print("Received an int.")
print_type(1)
print_type("This is a string.")
```
最後のケースは
`addpattern`
ただし、残りのすべてのケースをキャッチすることを意図している場合は、関数はパターンマッチング関数である必要はありません。
この間違いをキャッチするには、
`addpattern`
は、パターンマッチング関数ではないと判断されたものが渡された場合に警告を発します。ただし、元のパターンマッチング関数が何らかの方法でラップされている場合、この警告は誤っている場合があります。その場合は、
`allow_any_func=True`
警告を無視します。
##### 例
**ココナッツ:**
```coconut
def factorial(0) = 1
@addpattern(factorial)
def factorial(n) = n * factorial(n - 1)
```
_パターン マッチング関数に新しいパターンを追加する簡単な例_
```coconut
"[A], [B]" |> windowsof$(3) |> map$(addpattern(
(def (("[","A","]")) => "A"),
(def (("[","B","]")) => "B"),
(def ((_,_,_)) => None),
)) |> filter$((.is None) ..> (not)) |> list |> print
```
_使用例
`addpattern`
機能は[
`addpattern`
_
**Python:**
_複雑なデコレータ定義と、各パターン マッチングの長い一連のチェックなしでは実行できません。Python 構文については、コンパイルされたコードを参照してください。_
#####
`prepattern`
**非推奨:** ココナッツには
`prepattern`
組み込みで、逆の順序でパターンを追加します
`addpattern`
;
`prepattern`
は次のように定義されます:
```coconut_python
def prepattern(base_func):
"""Decorator to add a new case to a pattern-matching function,
where the new case is checked first."""
def pattern_prepender(func):
return addpattern(func)(base_func)
return pattern_prepender
```
_注: 合格
`--strict`
非推奨の機能を無効にします。_
####
`memoize`
**メモ化**(_maxsize_=
`None`
、_入力_=
`False`
)
**memoize**(_user\_function_)
ココナッツは
`functools.lru_cache`
組み込みとして
`memoize`
_maxsize_パラメータが次のように変更されます
`None`
デフォルトでは。
`memoize`
再帰関数の最適化のユースケースが容易になります。_maxsize_が
`None`
その場合、通常はそれが望ましいです。
の使用
`memoize`
必要
`functools.lru_cache`
これはPython 3の標準ライブラリに存在しますが、Python 2では
`pip install backports.functools_lru_cache`
機能します。さらに、Python 2および
`backports.functools_lru_cache`
ココナッツが存在する場合、パッチを当てます
`functools`
そのような
`functools.lru_cache = backports.functools_lru_cache.lru_cache`
.
メモ化される関数がジェネレーターであるか、イテレータを返す場合、[
`recursive_generator`
](#recursive_generator) も同様の効果を得るために使用できます。再帰ジェネレーターにはこれを使用する必要があります。
##### Python ドキュメント
@**memoize**(_user\_function_)
@**memoize**(_maxsize=None, typed=False_)
関数を、_maxsize_ 個までの最新の呼び出しを保存するメモ化呼び出し可能オブジェクトでラップするデコレータ。高価な関数や I/O にバインドされた関数が同じ引数で定期的に呼び出される場合に、時間を節約できます。
結果をキャッシュするために辞書が使用されるため、関数の位置引数とキーワード引数はハッシュ可能である必要があります。
異なる引数パターンは、別々のキャッシュ エントリを持つ異なる呼び出しと見なすことができます。たとえば、
`f(a=1, b=2)`
そして
`f(b=2, a=1)`
キーワード引数の順序が異なり、2 つの別々のキャッシュ エントリが存在する可能性があります。
_user\_function_ が指定されている場合は、呼び出し可能でなければなりません。これにより、_memoize_ デコレータをユーザー関数に直接適用して、maxsize をデフォルト値のままにすることができます。
`None`
```coconut_python
@memoize
def count_vowels(sentence):
return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')
```
_maxsize_が
`None`
、LRU 機能は無効になり、キャッシュは無制限に増大する可能性があります。
_typed_ が true に設定されている場合、異なる型の関数引数は別々にキャッシュされます。typed が false の場合、実装は通常それらを同等の呼び出しと見なし、単一の結果のみをキャッシュします。(str や int などの一部の型は、typed が false であっても別々にキャッシュされる場合があります。)
型の特異性は関数の直接引数にのみ適用され、その内容には適用されないことに注意してください。スカラー引数、
`Decimal(42)`
そして
`Fraction(42)`
異なる結果を持つ異なる呼び出しとして扱われます。対照的に、タプル引数
`('answer', Decimal(42))`
そして
`('answer', Fraction(42))`
同等として扱われます。
デコレータはまた、
`cache_clear()`
キャッシュをクリアまたは無効化する関数。
元の基盤関数は、
`__wrapped__`
属性。これは、イントロスペクション、キャッシュのバイパス、または別のキャッシュで関数を再ラップする場合に役立ちます。
キャッシュは、引数と戻り値への参照を、キャッシュから期限切れになるかキャッシュがクリアされるまで保持します。
メソッドがキャッシュされている場合、
`self`
インスタンス引数はキャッシュに含まれています。[メソッド呼び出しをキャッシュするにはどうすればよいですか?](https://docs.python.org/3/faq/programming.html#faq-cache-method-calls) を参照してください。
[LRU (最近最も使用されていない) キャッシュ](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) は、最新の呼び出しが今後の呼び出しの最良の予測子である場合に最も効果的です (たとえば、ニュース サーバーで最も人気のある記事は毎日変わる傾向があります)。キャッシュのサイズ制限により、Web サーバーなどの長時間実行されるプロセスでキャッシュが無制限に増加することはありません。
一般に、LRU キャッシュは、以前に計算された値を再利用する場合にのみ使用する必要があります。したがって、副作用のある関数、呼び出しごとに個別の可変オブジェクトを作成する必要がある関数、または time() や random() などの不純な関数をキャッシュすることは意味がありません。
キャッシュを使用して動的プログラミング手法を実装し、フィボナッチ数を効率的に計算する例:
```coconut_pycon
@memoize
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
```
##### 例
**ココナッツ:**
```coconut
def fib(n if n < 2) = n
@memoize
@addpattern(fib)
def fib(n) = fib(n-1) + fib(n-2)
```
**Python:**
```coconut_python
try:
from functools import lru_cache
except ImportError:
from backports.functools_lru_cache import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
```
####
`override`
**override**(_func_)
Coconut は
`@override`
デコレータを使用すると、サブクラス内のメソッド定義を親クラスのメソッドのオーバーライドとして宣言できます。
`@override`
メソッドで使用されている場合、同じ名前のメソッドが親クラスに存在しない場合、クラス定義はエラーを発生させます。
`RuntimeError`
。
`@override`
他のデコレータと連携して動作します。
`@classmethod`
そして
`@staticmethod`
ただし、
`@override`
最も外側のデコレータです。
さらに、
`override`
型チェッカーには次のように表示されます [
`typing_extensions.override`
](https://pypi.org/project/typing-extensions/)。
##### 例
**Coconut:**
```coconut
class A:
x = 1
def f(self, y) = self.x + y
class B:
@override
def f(self, y) = self.x + y + 1
```
**Python:**
_長いデコレータ定義がなければ実行できません。Python のデコレータの完全な定義は、Coconut ヘッダーにあります。_
####
`recursive_generator`
**recursive\_generator**(_func_)
Coconut は
`recursive_generator`
メモ化して[
`reiterable`
](#reiterable) イテレータを返すジェネレータやその他のステートレス関数。
`recursive_generator`
関数では、次の基準を満たす必要があります:
1. 関数は常に
`return`
イテレータを生成するか、イテレータを生成する
`yield`
、
2. 同じ引数で複数回呼び出されると、関数は同じイテレータを生成します (関数はステートレスです)。
3. 関数は同じ引数で複数回呼び出されます (通常は関数自体を呼び出します)。
重要なのは、
`recursive_generator`
また、これまで修正されていなかったPythonのイテレータロジックの厄介なセグメンテーションフォールトを解決することもできます。(http://bugs.python.org/issue14010) 具体的には、
```coconut
seq = get_elem() :: seq
```
前述のPythonの問題によりクラッシュする場合は、次のように記述します。
```coconut
@recursive_generator
def seq() = get_elem() :: seq()
```
問題なく動作します。
作業中に注意すべき落とし穴が1つあります
`recursive_generator`
同じイテレータ オブジェクトを入力として関数が複数回呼び出される可能性があるが、そのオブジェクトが実際には同じ項目に対応していないコンテキストでは使用しないでください (たとえば、1 回目にオブジェクトがまだ反復処理されておらず、2 回目に反復処理されているため)。
_非推奨:
`recursive_iterator`
は非推奨のエイリアスとして利用可能です
`recursive_generator`
廃止予定の機能は、
`--strict`
mode._
##### 例
**ココナッツ:**
```coconut
@recursive_generator
def fib() = (1, 1) :: map((+), fib(), fib()$[1:])
```
**Python:**
_長いデコレータ定義がなければ実行できません。Python のデコレータの完全な定義は、Coconut ヘッダーにあります。_
### 組み込み型
```{contents}
---
local:
depth: 1
---
```
####
`multiset`
**マルチセット**(_反復可能_=
`None`
、/、**kwds)
ココナッツは
`multiset`
[の組み込みサブクラスとして
`collections.Counter`
](https://docs.python.org/3/library/collections.html#collections.Counter) は、完全な [Set および MutableSet インターフェース](https://docs.python.org/3/library/collections.abc.html) も実装しています。
マルチセットを簡単に構築できるように、Coconut は [マルチセット リテラル](#set-literals) も提供しています。
によって提供される新しいメソッド
`multiset`
上に
`collections.Counter`
:
- multiset.**add**(_item_): マルチセットに要素を追加します。
- multiset.**discard**(_item_): マルチセットのメンバーである場合、その要素を削除します。
- multiset.**remove**(_item_): マルチセットから要素を削除します。メンバーである必要があります。
- multiset.**isdisjoint**(_other_): 2 つのマルチセットに null 交差がある場合は True を返します。
- multiset.**\_\_xor\_\_**(_other_): 2 つのマルチセットの対称差を新しいマルチセットとして返します。具体的には、次のようになります。
`a ^ b = (a - b) | (b - a)`
- multiset.**count**(_item_): マルチセット内の要素の出現回数を返します。
`multiset[item]`
、さらにカウントが非負であることを確認します。
- multiset.**\_\_fmap\_\_**(_func_): カウントを保存しながら、マルチセットの内容に関数を適用します。[
`fmap`
](#fmap)。
Coconut では、
`multiset`
[豊富な比較と
`Counter.total()`
](https://docs.python.org/3/library/collections.html#collections.Counter) はすべての Python バージョンで使用できます。
##### 例
**Coconut:**
```coconut
my_multiset = m{1, 1, 2}
my_multiset.add(3)
my_multiset.remove(2)
print(my_multiset)
```
**Python:**
```coconut_python
from collections import Counter
my_counter = Counter((1, 1, 2))
my_counter[3] += 1
my_counter[2] -= 1
if my_counter[2] <= 0:
del my_counter[2]
print(my_counter)
```
####
`Expected`
**予想**(_result_=
`None`
、_エラー_=
`None`
)
ココナッツ
`Expected`
ココナッツが内蔵されている[
`data`
型](#data)は、Haskellの[に似た、エラーであるかもしれないしそうでないかもしれない値を表します。
`Either`
](https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-Either.html)。
`Expected`
実質的には次のものと同等です。
```coconut
data Expected[T](result: T? = None, error: BaseException? = None):
def __bool__(self) -> bool:
return self.error is None
def __fmap__[U](self, func: T -> U) -> Expected[U]:
"""Maps func over the result if it exists.
__fmap__ should be used directly only when fmap is not available (e.g. when consuming an Expected in vanilla Python).
"""
return self.__class__(func(self.result)) if self else self
def and_then[U](self, func: T -> Expected[U]) -> Expected[U]:
"""Maps a T -> Expected[U] over an Expected[T] to produce an Expected[U].
Implements a monadic bind. Equivalent to fmap ..> .join()."""
return self |> fmap$(func) |> .join()
def join(self: Expected[Expected[T]]) -> Expected[T]:
"""Monadic join. Converts Expected[Expected[T]] to Expected[T]."""
if not self:
return self
if not self.result `isinstance` Expected:
raise TypeError("Expected.join() requires an Expected[Expected[_]]")
return self.result
def map_error(self, func: BaseException -> BaseException) -> Expected[T]:
"""Maps func over the error if it exists."""
return self if self else self.__class__(error=func(self.error))
def handle(self, err_type, handler: BaseException -> T) -> Expected[T]:
"""Recover from the given err_type by calling handler on the error to determine the result."""
if not self and isinstance(self.error, err_type):
return self.__class__(handler(self.error))
return self
def expect_error(self, *err_types: BaseException) -> Expected[T]:
"""Raise any errors that do not match the given error types."""
if not self and not isinstance(self.error, err_types):
raise self.error
return self
def unwrap(self) -> T:
"""Unwrap the result or raise the error."""
if not self:
raise self.error
return self.result
def or_else[U](self, func: BaseException -> Expected[U]) -> Expected[T | U]:
"""Return self if no error, otherwise return the result of evaluating func on the error."""
return self if self else func(self.error)
def result_or_else[U](self, func: BaseException -> U) -> T | U:
"""Return the result if it exists, otherwise return the result of evaluating func on the error."""
return self.result if self else func(self.error)
def result_or[U](self, default: U) -> T | U:
"""Return the result if it exists, otherwise return the default.
Since .result_or() completely silences errors, it is highly recommended that you
call .expect_error() first to explicitly declare what errors you are okay silencing.
"""
return self.result if self else default
```
`Expected`
は主に[の戻り値の型として使用されます
`safe_call`
](#safe_call)。
一般的に、最も良い使用方法は
`Expected`
[と
`fmap`
](#fmap)は、結果が存在する場合は関数を適用し、存在しない場合はエラーを保持します。複数の
`Expected`
-返却操作、
`.and_then`
代わりに使用してください
`fmap`
特定のエラーを処理するには、次のパターンを使用します。
```
safe_call(might_raise_IOError).handle(IOError, const 10).unwrap()
safe_call(might_raise_IOError).expect_error(IOError).result_or(10)
```
対戦相手に
`Expected`
、 ただ:
```
Expected(res) = Expected("result")
Expected(error=err) = Expected(error=TypeError())
```
##### 例
**ココナッツ:**
```coconut
def try_divide(x: float, y: float) -> Expected[float]:
try:
return Expected(x / y)
except Exception as err:
return Expected(error=err)
try_divide(1, 2) |> fmap$(.+1) |> print
try_divide(1, 0) |> fmap$(.+1) |> print
```
**Python:**
_複雑なものがなければ実行できません
`Expected`
定義。Python 構文についてはコンパイルされたコードを参照してください。_
####
`MatchError`
あ
`MatchError`
[分割代入](#destructuring-assignment)または[パターンマッチング関数](#pattern-matching-functions)が失敗したときに発生し、したがって
`MatchError`
これらのエラーをキャッチするための組み込み機能が提供されています。
`MatchError`
オブジェクトは次の 3 つの属性をサポートします。
`pattern`
失敗したパターンを記述する文字列です。
`value`
、これはそのパターンに一致しなかったオブジェクトです。
`message`
これは完全なエラーメッセージです。不要な
`repr`
通話、
`MatchError`
計算するのは
`message`
実際にリクエストされると、
さらに、[ビューパターン](#match)を使用している場合は、独自の
`MatchError`
(ただし、分割代入やパターンマッチング関数定義を使用することもできます)。独自の
`MatchError`
、 ただ
`raise MatchError(pattern, value)`
(両方の引数はオプションです)。
複数の Coconut パッケージが同時にインストールされている場合、複数の
`MatchError`
異なるパッケージで定義されているもの。Coconutは、これらのすべてが確実に機能するように、裏で魔法をかけています。
`MatchError`
sはシームレスに相互運用できますが、そのようなパッケージがすべて[
`--package`
モードではなく
`--standalone`
モード](#compilation-modes)。
###
`CoconutWarning`
`CoconutWarning`
は[
`Warning`
](https://docs.python.org/3/library/exceptions.html#Warning) サブクラスは、すべてのランタイム Coconut 警告に使用されます。[
`warnings`
](https://docs.python.org/3/library/warnings.html)。
### 汎用組み込み関数
```{contents}
---
local:
depth: 1
---
```
####
`makedata`
**makedata**(_data\_type_, *_args_)
Coconut は
`makedata`
希望する型と内容を指定してコンテナを構築する関数。これは、[
`data`
](#data) 型を上書きすることで
`__new__`
、Coconutで作成されたデータ型の基本コンストラクタに直接アクセスできるため
`data`
声明。
`makedata`
最初の引数として構築するデータ型を取り、残りの引数としてそのコンテナーに配置するオブジェクトを取ります。
`makedata`
[の基になるコンストラクタを抽出するためにも使用できます。
`match data`
](#match-data) 型は、通常のパターン マッチング コンストラクターをバイパスします。
さらに、
`makedata`
非
`data`
最初の引数として型を指定すると、指定された引数で指定された型のオブジェクトを構築しようとします。この機能は内部的に
`fmap`
.
#####
`datamaker`
**非推奨:** ココナッツには
`datamaker`
組み込み、部分的に適用される
`makedata`
;
`datamaker`
は次のように定義されます:
```coconut
def datamaker(data_type):
"""Get the original constructor of the given data type or class."""
return makedata$(data_type)
```
_注: 合格
`--strict`
非推奨の機能を無効にします。_
##### 例
**Coconut:**
```coconut
data Tuple(elems):
def __new__(cls, *elems):
return elems |> makedata$(cls)
```
**Python:**
_各データ型の一連のメソッド定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
####
`fmap`
**fmap**(_func_, _obj_)
Haskell では、
`fmap(func, obj)`
データ型を取る
`obj`
そして、新しいデータ型を返します。
`func`
コンテンツにマッピング。ココナッツの
`fmap`
この関数は、Coconut の [データ型](#data) に対してもまったく同じことを行います。
`fmap`
組み込みオブジェクトにも使用可能
`str`
、
`dict`
、
`list`
、
`tuple`
、
`set`
、
`frozenset`
、
`bytes`
、
`bytearray`
、 そして
`dict`
の変種として
`map`
同じタイプのオブジェクトを返します。
`dict`
、またはその他の
`collections.abc.Mapping`
、
`fmap`
マッピングの
`.items()`
デフォルトの反復処理の代わりに
`.keys()`
、新しいマッピングはマップされた項目から再構築されます。_非推奨:
`fmap$(starmap_over_mappings=True)`
意思
`starmap`
上
`.items()`
の代わりに
`map`
_
非同期反復可能オブジェクトの場合、
`fmap`
非同期にマッピングされるため、
`fmap`
その場合は
```coconut_python
async def fmap_over_async_iters(func, async_iter):
async for item in async_iter:
yield func(item)
```
そのような
`fmap`
非同期マップとして効果的に使用できます。
外部ライブラリの一部のオブジェクトにも特別なサポートが提供されます:
* [
`numpy`
](#numpy-integration) オブジェクト、
`fmap`
[ を使用します
`np.vectorize`
](https://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html) を実行して結果を生成します。
* [
`pandas`
](https://pandas.pydata.org/) オブジェクト、
`fmap`
[ を使用します
`.apply`
](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html) を最後の軸に沿って(つまり行ごとに)適用します。
`DataFrame`
's、要素ごとに
`Series`
's)。
* [
`xarray`
](https://docs.xarray.dev/en/stable/) オブジェクト、
`fmap`
まずそれらを
`pandas`
オブジェクト、適用
`fmap`
、そしてそれらを元に戻します。
`fmap`
特定のオブジェクトに対する
`__fmap__(self, func)`
いつでも呼び出されるマジックメソッド
`fmap`
そのオブジェクトに対して呼び出されます。
`__fmap__`
実装は常に [Functor 法則](https://wiki.haskell.org/Functor) を満たす必要があります。
_非推奨:
`fmap(func, obj, fallback_to_init=True)`
後退する
`obj.__class__(map(func, obj))`
いいえ
`fmap`
実装は、調達ではなく利用可能である
`TypeError`
._
##### 例
**ココナッツ:**
```coconut
[1, 2, 3] |> fmap$(x => x+1) == [2, 3, 4]
class Maybe
data Nothing() from Maybe
data Just(n) from Maybe
Just(3) |> fmap$(x => x*2) == Just(6)
Nothing() |> fmap$(x => x*2) == Nothing()
```
**Python:**
_各データ型の一連のメソッド定義がなければ実行できません。Python 構文についてはコンパイルされたコードを参照してください。_
####
`call`
**call**(_func_, /, *_args_, \*\*_kwargs_)
ココナッツ
`call`
単純に関数適用を実装する。つまり、
`call`
実質的には
```coconut
def call(f, /, *args, **kwargs) = f(*args, **kwargs)
```
`call`
は、ポイントフリースタイルで記述する場合に関数適用のための [演算子関数](#operator-functions) として主に役立ちます。
_非推奨:
`of`
は非推奨のエイリアスとして利用可能です
`call`
廃止予定の機能は、
`--strict`
モード。_
####
`safe_call`
**safe_call**(_func_, /, *_args_, \*\*_kwargs_)
ココナッツの
`safe_call`
は[
`call`
](#call) は、
`Exception`
s と [ を返します。
`Expected`
](#expected) には結果またはエラーのいずれかが含まれます。
`safe_call`
実質的には以下と同等です:
```coconut
def safe_call(f, /, *args, **kwargs):
try:
return Expected(f(*args, **kwargs))
except Exception as err:
return Expected(error=err)
```
常に
`Expected`
エラーを発生させるのではなく、単に
`@safe_call$`
.
##### 例
**ココナッツ:**
```coconut
res, err = safe_call(=> 1 / 0) |> fmap$(.+1)
```
**Python:**
_複雑なものがなければ実行できません
`Expected`
定義。Python 構文についてはコンパイルされたコードを参照してください。_
####
`ident`
**ident**(_x_, *, _side\_effect_=
`None`
)
ココナッツ
`ident`
は恒等関数であり、一般的には
`x => x`
。
`ident`
キーワードのみの引数も1つ受け入れます。
`side_effect`
は、引数が返される前に呼び出す関数を指定します。つまり、
`ident`
実質的には以下と同等です:
```coconut
def ident(x, *, side_effect=None):
if side_effect is not None:
side_effect(x)
return x
```
`ident`
は、ポイントフリースタイルで書くときに主に便利です(例えば、[
`lift`
](#lift)) または [pipes](#pipes) をデバッグする場合、
`ident$(side_effect=print)`
パイプされている内容を確認できます。
####
`const`
**const**(_value_)
ココナッツの
`const`
引数が何であれ、与えられた値を返す関数を単純に構築します。つまり、
`const`
は、
```coconut
def const(value) = (*args, **kwargs) => value
```
`const`
は、ポイントフリースタイルで書くときに主に便利です(例えば、[
`lift`
](#lift))。
####
`flip`
**反転**(_func_, _nargs_=
`None`
)
ココナッツ
`flip(f, nargs=None)`
は高階関数であり、関数
`f`
は、引数の順序を逆にした新しい関数を返します。
`nargs`
通過すると、最初の
`nargs`
引数は逆になります。
バイナリの場合、
`flip`
として機能します
```coconut
flip(f, 2)(x, y) == f(y, x)
```
そのような
`flip$(?, 2)`
を実装する
`C`
コンビネータ(
`flip`
Haskell の場合)
一般的なケースでは、
`flip`
は、
```coconut
def flip(f, nargs=None) =
(*args, **kwargs) => (
f(*args[::-1], **kwargs) if nargs is None
else f(*(args[nargs-1::-1] + args[nargs:]), **kwargs)
)
```
####
`lift`
そして
`lift_apart`
##### **lift**(_func_)
##### **lift**(_func_, *_func\_args_, **_func\_kwargs_)
ココナッツ
`lift`
組み込み関数は、関数を取り込み、その引数がすべて関数になるように「持ち上げる」高階関数です。
簡単な例として、バイナリ関数の場合
`f(x, y)`
2つの単項関数
`g(z)`
そして
`h(z)`
、
`lift`
として機能します
```coconut
lift(f)(g, h)(z) == f(g(z), h(z))
```
この場合
`lift`
を実装する
`S'`
コンビネータ(
`liftA2`
または
`liftM2`
Haskell の場合)
一般的なケースでは、
`lift`
は、
```coconut
def lift(f) = (
(*func_args, **func_kwargs) =>
(*args, **kwargs) =>
f(
*(g(*args, **kwargs) for g in func_args),
**{k: h(*args, **kwargs) for k, h in func_kwargs.items()}
)
)
```
`lift`
ショートカットフォームもサポートしており、
`lift(f, *func_args, **func_kwargs)`
は以下と同等である
`lift(f)(*func_args, **func_kwargs)`
.
##### **lift\_apart**(_func_)
##### **lift\_apart**(_func_, *_func\_args_, **_func\_kwargs_)
ココナッツ
`lift_apart`
組み込みは、
`lift`
ただし、各関数の最終引数を重複させるのではなく、分離します。
バイナリ関数の場合
`f(x, y)`
2つの単項関数
`g(z)`
そして
`h(z)`
、
`lift_apart`
として機能します
```coconut
lift_apart(f)(g, h)(z, w) == f(g(z), h(w))
```
この場合
`lift_apart`
を実装する
`D2`
コンビネータ。
一般的なケースでは、
`lift_apart`
は、
```coconut
def lift_apart(f) = (
(*func_args, **func_kwargs) =>
(*args, **kwargs) =>
f(
*(f(x) for f, x in zip(func_args, args, strict=True)),
**{k: func_kwargs[k](kwargs[k]) for k in func_kwargs.keys() | kwargs.keys()},
)
)
```
`lift_apart`
同じショートカット形式をサポートします
`lift`
.
##### 例
**ココナッツ:**
```coconut
xs_and_xsp1 = ident `lift(zip)` map$(=>_+1)
min_and_max = lift(,)(min, max)
plus_and_times = (+) `lift(,)` (*)
```
**Python:**
```coconut_python
def xs_and_xsp1(xs):
return zip(xs, map(lambda x: x + 1, xs))
def min_and_max(xs):
return min(xs), max(xs)
def plus_and_times(x, y):
return x + y, x * y
```
**ココナッツ:**
```coconut
first_false_and_last_true = (
lift(,)(ident, reversed)
..*> lift_apart(,)(dropwhile$(bool), dropwhile$(not))
..*> lift_apart(,)(.$[0], .$[0])
)
```
**Python:**
```coconut_python
from itertools import dropwhile
def first_false_and_last_true(xs):
rev_xs = reversed(xs)
return (
next(dropwhile(bool, xs)),
next(dropwhile(lambda x: not x, rev_xs)),
)
```
####
`and_then`
そして
`and_then_await`
**and\_then**(_first\_async\_func_, _second\_func_)
**and\_then\_await**(_first\_async\_func_, _second\_async\_func_)
Coconut は
`and_then`
そして
`and_then_await`
作曲用のビルトイン
`async`
関数。具体的には:
* 非同期関数を前方に作成するには
`async_f`
通常の機能を持つ
`g`
(つまり
`g`
の結果に基づいて呼び出されます
`await`
ing
`async_f`
)、 書く
``
非同期
`and_then`
グ
``
.
* 非同期関数を前方に作成するには
`async_f`
別の非同期関数で
`async_g`
(つまり
`async_g`
の結果に基づいて呼び出されます
`await`
ing
`async_f`
、 その後
`async_g`
それ自体が期待されている)、書く
``
非同期
`and_then_await`
非同期
``
.
* 通常の関数を前方に合成するには
`f`
非同期関数で
`async_g`
(つまり
`async_g`
の結果に基づいて呼び出されます
`f`
)、単に
`f ..> async_g`
.
上記のすべては、常に結果として生じる構成が
`async`
関数。
組み込み関数は実質的に次の関数と同等です。
```coconut
def and_then[**T, U, V](
first_async_func: async (**T) -> U,
second_func: U -> V,
) -> async (**T) -> V =
async def (*args, **kwargs) => (
first_async_func(*args, **kwargs)
|> await
|> second_func
)
def and_then_await[**T, U, V](
first_async_func: async (**T) -> U,
second_async_func: async U -> V,
) -> async (**T) -> V =
async def (*args, **kwargs) => (
first_async_func(*args, **kwargs)
|> await
|> second_async_func
|> await
)
```
通常の[関数合成](#function-composition)と同様に、
`and_then`
そして
`and_then_await`
構成の最初の関数に添付されたすべてのメタデータが保持されます。
##### 例
**Coconut:**
```coconut
load_and_send_data = (
load_data_async()
`and_then` proc_data
`and_then_await` send_data
)
```
**Python:**
```coconut_python
async def load_and_send_data():
return await send_data(proc_data(await load_data_async()))
```
### イテレータを操作するための組み込み関数
```{contents}
---
local:
depth: 1
---
```
#### 強化されたビルトイン
ココナッツ
`map`
、
`zip`
、
`filter`
、
`reversed`
、 そして
`enumerate`
オブジェクトは、Python の同等機能の拡張バージョンであり、次の機能をサポートしています:
- 基礎となるイテレータが複数回反復できる場合、複数回反復する機能。
- _注: これにより、Coconut 組み込みと Python 組み込みの動作が異なる場合があります。
`py_`
Python の動作が必要な場合は、バージョンを確認してください。_
-
`reversed`
-
`repr`
- 最適化された通常の(およびイテレータの)インデックス作成/スライス(
`map`
、
`zip`
、
`reversed`
、 そして
`enumerate`
しかし、
`filter`
)。
-
`len`
(すべてを除く
`filter`
) (けれど
`bool`
常に成果を上げる
`True`
)。
- [PEP 618](https://www.python.org/dev/peps/pep-0618)
`zip(..., strict=True)`
すべてのPythonバージョンでサポート。
- 追加
`strict=True`
サポートする
`map`
同様に(複数の反復可能オブジェクトがある場合、反復可能オブジェクトの長さが同じになるように強制します。
`zip`
裏ではエラーは次のように表示されます
`zip(..., strict=True)`
エラー)。
- サブクラスがオブジェクトの元の引数を取得するために使用できる属性を追加しました:
*
`map`
:
`func`
、
`iters`
*
`zip`
:
`iters`
*
`filter`
:
`func`
、
`iter`
*
`reversed`
:
`iter`
*
`enumerate`
:
`iter`
、
`start`
##### 他のビルトインへのインデックス作成
Coconut はランダムアクセスのインデックス作成/スライス機能を提供しますが、
`range`
、
`map`
、
`zip`
、
`reversed`
、 そして
`enumerate`
、Coconutは組み込みのインデックスを作成できません。
`filter`
、
`takewhile`
、 または
`dropwhile`
直接行う効率的な方法がないためです。
```coconut
range(10) |> filter$(i => i>3) |> .[0] # doesn't work
```
これを機能させるには、イテレータ スライスを明示的に使用できますが、一般的なケースでは効率が悪くなります。
```coconut
range(10) |> filter$(i => i>3) |> .$[0]
```
Coconut のイテレータ スライシングの詳細については、[こちら](#iterator-slicing) を参照してください。
##### 例
**Coconut:**
```coconut
map((+), range(5), range(6)) |> len |> print
range(10) |> filter$((x) => x < 5) |> reversed |> tuple |> print
```
**Python:**
_カスタム定義なしでは実行できません
`map`
タイプ。
`map`
Coconut ヘッダーで確認できます。_
**Coconut:**
```coconut
range(0, 12, 2)[4]
map((i => i*2), range(10))[2]
```
**Python:**
_Coconut の反復可能なインデックスなしでは、多くの複雑な部分を必要とするため、すぐには実行できません。Python で必要な定義は、Coconut ヘッダーにあります。_
####
`reduce`
**reduce**(_function_, _iterable_[, _initial_])
Coconut は Python 2 の
`reduce`
内蔵、使用
`functools.reduce`
バージョン。さらに、
`functools.reduce`
、ココナッツ
`reduce`
キーワード引数は常にサポートされます。
##### Python ドキュメント
**reduce**(_function, iterable_**[**_, initial_**]**)
2 つの引数の _function_ を _sequence_ の項目に左から右へ累積的に適用し、シーケンスを 1 つの値に減らします。たとえば、
`reduce((x, y) => x+y, [1, 2, 3, 4, 5])`
計算する
`((((1+2)+3)+4)+5)`
左の引数 _x_ は累積値で、右の引数 _y_ は _sequence_ からの更新値です。オプションの _initial_ が存在する場合、計算ではシーケンスの項目の前に配置され、シーケンスが空の場合にデフォルトとして機能します。_initial_ が指定されておらず、_sequence_ に項目が 1 つしか含まれていない場合は、最初の項目が返されます。
##### 例
**Coconut:**
```coconut
product = reduce$(*)
range(1, 10) |> product |> print
```
**Python:**
```coconut_python
import operator
import functools
product = functools.partial(functools.reduce, operator.mul)
print(product(range(1, 10)))
```
####
`reiterable`
**反復可能**(_iterable_)
`reiterable`
与えられた反復可能オブジェクトをラップして、
`reiterable`
繰り返しても同じ結果が返されます。結果は必ずしも
`reiterable`
指定された反復可能オブジェクトがすでに反復可能である場合はオブジェクト。
`reiterable`
[ 使用
`tee`
](#tee) フードの下と
`tee`
代わりに使うこともできるが
`reiterable`
一般的に推奨されるのは
`tee`
.
##### 例
**ココナッツ:**
```coconut
def list_type(xs):
match reiterable(xs):
case [fst, snd] :: tail:
return "at least 2"
case [fst] :: tail:
return "at least 1"
case (| |):
return "empty"
```
**Python:**
_それぞれについて長い一連のチェックを行わないと実行できません
`match`
ステートメント。Python 構文についてはコンパイルされたコードを参照してください。_
####
`starmap`
**starmap**(_function_, _iterable_)
Coconut は、
`itertools.starmap`
サポートする
`reversed`
、
`repr`
、最適化された通常スライス(およびイテレータスライス)
`len`
、 そして
`func`
/
`iter`
属性。
##### Python ドキュメント
**starmap**(_function, iterable_)
反復可能オブジェクトから取得した引数を使用して関数を計算する反復子を作成します。
`map()`
引数パラメータがすでに単一の反復可能オブジェクトからタプルにグループ化されている場合(データは「事前に圧縮」されている)。
`map()`
そして
`starmap()`
の区別と似ている
`function(a,b)`
そして
`function(*c)`
ほぼ次のものと同等です:
```coconut_python
def starmap(function, iterable):
for args in iterable:
yield function(*args)
```
##### 例
**ココナッツ:**
```coconut
range(1, 5) |> map$(range) |> starmap$(print) |> consume
```
**Python:**
```coconut_python
import itertools, collections
collections.deque(itertools.starmap(print, map(range, range(1, 5))), maxlen=0)
```
####
`zip_longest`
**zip\_longest**(*_iterables_、_fillvalue_=
`None`
)
ココナッツは、
`itertools.zip_longest`
組み込みとして
`zip_longest`
。
`zip_longest`
Coconutの[拡張zip](#enhanced-built-ins)と同じ機能をすべてサポートし、さらに追加属性もサポートします。
`fillvalue`
.
##### Python ドキュメント
**zip\_longest**(_\*iterables, fillvalue=None_)
各反復可能オブジェクトから要素を集約する反復子を作成します。反復可能オブジェクトの長さが不均等な場合、欠落している値は _fillvalue_ で埋められます。反復は最長の反復可能オブジェクトがなくなるまで続行されます。おおよそ次のコードと同等です。
```coconut_python
def zip_longest(*args, fillvalue=None):
iterators = [iter(it) for it in args]
num_active = len(iterators)
if not num_active:
return
while True:
values = []
for i, it in enumerate(iterators):
try:
value = next(it)
except StopIteration:
num_active -= 1
if not num_active:
return
iterators[i] = repeat(fillvalue)
value = fillvalue
values.append(value)
yield tuple(values)
```
反復可能オブジェクトの1つが潜在的に無限である場合、
`zip_longest()`
関数は、呼び出し回数を制限するもの(例えばイテレータのスライスや
`takewhile`
)。指定されていない場合は、_fillvalue_はデフォルトで
`None`
.
##### 例
**ココナッツ:**
```coconut
result = zip_longest(range(5), range(10))
```
**Python:**
```coconut_python
import itertools
result = itertools.zip_longest(range(5), range(10))
```
####
`takewhile`
**takewhile**(_predicate_, _iterable_)
Coconut は
`itertools.takewhile`
組み込みとして
`takewhile`
さらに、
`itertools.takewhile`
、ココナッツ
`takewhile`
キーワード引数は常にサポートされます。
##### Python ドキュメント
**takewhile**(_predicate, iterable_)
_predicate_ が true である限り、_iterable_ から要素を返すイテレータを作成します。次と同等です:
```coconut_python
def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break
```
##### 例
**ココナッツ:**
```coconut
negatives = numiter |> takewhile$(x => x < 0)
```
**Python:**
```coconut_python
import itertools
negatives = itertools.takewhile(lambda x: x < 0, numiter)
```
####
`dropwhile`
**dropwhile**(_predicate_, _iterable_)
Coconut は
`itertools.dropwhile`
組み込みとして
`dropwhile`
さらに、
`itertools.dropwhile`
、ココナッツ
`dropwhile`
キーワード引数は常にサポートされます。
##### Python ドキュメント
**dropwhile**(_predicate, iterable_)
_predicate_ が true である限り、_iterable_ から要素を削除する反復子を作成します。その後、すべての要素を返します。注: 反復子は、述語が最初に false になるまで出力を生成しないため、起動に時間がかかる場合があります。次と同等です:
```coconut_python
def dropwhile(predicate, iterable):
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x
```
##### 例
**ココナッツ:**
```coconut
positives = numiter |> dropwhile$(x => x < 0)
```
**Python:**
```coconut_python
import itertools
positives = itertools.dropwhile(lambda x: x < 0, numiter)
```
####
`flatten`
**平坦化**(_iterable_, _levels_=
`1`
)
ココナッツは、
`itertools.chain.from_iterable`
組み込みとして
`flatten`
追加のサポート
`reversed`
、
`repr`
、
`in`
、
`.count()`
、
`.index()`
、 そして
`fmap`
.
デフォルトでは、
`flatten`
指定された反復可能オブジェクト/配列の最上位レベルのみを平坦化します。ただし、_levels_ が渡された場合は、平坦化されるレベルの数を制御するために使用できます。
`0`
つまり、平坦化は起こらず、
`None`
見つかった反復可能オブジェクトをできるだけ多く平坦化します。_levels_が非
`None`
値の場合、最初の _levels_ レベルは反復可能オブジェクトである必要があります。そうでない場合はエラーが発生します。
##### Python ドキュメント
chain.**from_iterable**(_iterable_)
代替コンストラクタ
`chain()`
遅延評価される単一の反復可能な引数から連鎖入力を取得します。おおよそ次の式と同等です:
```coconut_python
def flatten(iterables):
for it in iterables:
for element in it:
yield element
```
##### 例
**ココナッツ:**
```coconut
iter_of_iters = [[1, 2], [3, 4]]
flat_it = iter_of_iters |> flatten |> list
```
**Python:**
```coconut_python
from itertools import chain
iter_of_iters = [[1, 2], [3, 4]]
flat_it = list(chain.from_iterable(iter_of_iters))
```
####
`scan`
**scan**(_function_, _iterable_[, _initial_])
Coconut は、
`itertools.accumulate`
引数の順序が逆の場合
`scan`
これもサポートしています
`repr`
、
`len`
、 そして
`func`
/
`iter`
/
`initial`
属性。
`scan`
[と全く同じように動作します
`reduce`
](#reduce) と同じですが、最後に累積された値のみを返すのではなく、すべての中間値の反復子を返します。
##### Python ドキュメント
**scan**(_function, iterable_**[**_, initial_**]**)
2 つの引数を持つ関数の累積結果を返す反復子を作成します。入力反復可能オブジェクトの要素は、_function_ の引数として受け入れられる任意の型にすることができます。(たとえば、加算演算の場合、要素は Decimal または Fraction を含む任意の加算可能な型にすることができます。) 入力反復可能オブジェクトが空の場合、出力反復可能オブジェクトも空になります。
_initial_ が指定されていない場合は、ほぼ次の式と同等です。
```coconut_python
def scan(function, iterable):
'Return running totals'
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = function(total, element)
yield total
```
##### 例
**ココナッツ:**
```coconut
input_data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
running_max = input_data |> scan$(max) |> list
```
**Python:**
```coconut_python
input_data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
running_max = []
max_so_far = input_data[0]
for x in input_data:
if x > max_so_far:
max_so_far = x
running_max.append(max_so_far)
```
####
`count`
**カウント**(_開始_=
`0`
、_ステップ_=
`1`
)
ココナッツは、
`itertools.count`
サポートする
`in`
、通常のスライス、最適化されたイテレータスライス、標準
`count`
そして
`index`
シーケンス法、
`repr`
、 そして
`start`
/
`step`
属性を組み込みとして
`count`
_step_パラメータが
`None`
、
`count`
次のように行動する
`itertools.repeat`
代わりに。
`count`
スライスをサポート、
`count()[...]`
のバージョンとして使用できます
`range`
場合によっては、より読みやすくなる。特に、誤って次のように書いてしまうことはよくある。
`range(10, 2)`
あなたが意図したとき
`range(0, 10, 2)`
、しかし、誤って書くことは難しい
`count()[10:2]`
あなたが意味するとき
`count()[:10:2]`
.
##### Python ドキュメント
**count**(_start=0, step=1_)
_start_ という数値から始まる等間隔の値を返すイテレータを作成します。
`map()`
連続したデータポイントを生成する。また、
`zip()`
シーケンス番号を追加します。おおよそ次のコードと同等です:
```coconut_python
def count(start=0, step=1):
n = start
while True:
yield n
if step:
n += step
```
##### 例
**ココナッツ:**
```coconut
count()$[10**100] |> print
```
**Python:**
_Coconut のイテレータ スライスなしでは、多くの複雑な部分を必要とするため、すぐには実行できません。Python で必要な定義は、Coconut ヘッダーにあります。_
####
`cycle`
**サイクル**(_iterable_, _times_=
`None`
)
ココナッツ
`cycle`
の修正版です
`itertools.cycle`
と
`times`
停止する前に _iterable_ を循環する回数を制御するパラメーター。
`cycle`
サポートも
`in`
、スライス、
`len`
、
`reversed`
、
`.count()`
、
`.index()`
、 そして
`repr`
.
##### Python ドキュメント
**cycle**(_iterable_)
反復可能オブジェクトから要素を返し、それぞれのコピーを保存する反復子を作成します。反復可能オブジェクトが使い果たされると、保存されたコピーから要素を返します。無限に繰り返します。ほぼ次のコードと同等です:
```coconut_python
def cycle(iterable):
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element
```
ツールキットのこのメンバーは、反復可能オブジェクトの長さに応じて、かなりの補助ストレージを必要とする場合があります。
##### 例
**Coconut:**
```coconut
cycle(range(2), 2) |> list |> print
```
**Python:**
```coconut_python
from itertools import cycle, islice
print(list(islice(cycle(range(2)), 4)))
```
####
`cartesian_product`
**カルテシアン\_積**(*_反復可能_、_繰り返し_=
`1`
)
ココナッツは、
`itertools.product`
組み込みとして
`cartesian_product`
追加のサポート
`len`
、
`repr`
、
`in`
、
`.count()`
、 そして
`fmap`
.
さらに、
`cartesian_product`
[の特別なサポートが含まれています
`numpy`
](#numpy-integration) オブジェクトの場合、反復子の代わりに多次元配列が返されます。
##### Python ドキュメント
**cartesian\_product**(_\*iterables, repeat=1_)
入力反復可能オブジェクトの直積。
ジェネレータ式内のネストされた for ループとほぼ同等です。たとえば、
`cartesian_product(A, B)`
同じものを返します
`((x,y) for x in A for y in B)`
.
ネストされたループは、オドメーターのように循環し、反復ごとに右端の要素が進みます。このパターンは辞書式順序を作成するため、入力の反復可能オブジェクトがソートされている場合、積タプルはソートされた順序で出力されます。
反復可能オブジェクトとそれ自体の積を計算するには、オプションの repeat キーワード引数を使用して繰り返し回数を指定します。たとえば、
`product(A, repeat=4)`
と同じ意味です
`cartesian_product(A, A, A, A)`
.
この関数は、実際の実装では中間結果をメモリに蓄積しないことを除けば、次のコードとほぼ同等です。
```coconut_python
def cartesian_product(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
```
前に
`cartesian_product()`
実行すると、入力反復可能オブジェクトを完全に消費し、積を生成するためにメモリ内に値のプールを保持します。したがって、有限の入力でのみ役立ちます。
##### 例
**Coconut:**
```coconut
v = [1, 2]
assert cartesian_product(v, v) |> list == [(1, 1), (1, 2), (2, 1), (2, 2)]
```
**Python:**
```coconut_python
from itertools import product
v = [1, 2]
assert list(product(v, v)) == [(1, 1), (1, 2), (2, 1), (2, 2)]
```
####
`multi_enumerate`
**multi\_enumerate**(_iterable_)
ココナッツ
`multi_enumerate`
反復可能オブジェクトの反復可能オブジェクトを列挙します。
`multi_enumerate`
enumerate と同じように動作しますが、内部反復可能オブジェクトをインデックスし、各内部反復可能オブジェクトのインデックスを表すタプル インデックスを生成します。インデックスをサポートします。
[
`numpy`
](#numpy-integration) オブジェクトは、[
`np.nditer`
](https://numpy.org/doc/stable/reference/generated/numpy.nditer.html) を裏でサポートしています。
`len`
のために [
`numpy`
](#numpy-integration) 配列。
##### 例
**ココナッツ:**
```coconut_pycon
>>> [1, 2;; 3, 4] |> multi_enumerate |> list
[((0, 0), 1), ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)]
```
**Python:**
```coconut_python
array = [[1, 2], [3, 4]]
enumerated_array = []
for i in range(len(array)):
for j in range(len(array[i])):
enumerated_array.append(((i, j), array[i][j]))
```
####
`groupsof`
**groupsof**(_n_, _iterable_, _fillvalue_=
`...`
)
ココナッツは
`groupsof`
反復可能オブジェクトを特定の長さのグループに分割する組み込み関数。具体的には、
`groupsof(n, iterable)`
分裂する
`iterable`
長さのタプルに
`n`
最後のタプルのみが潜在的にサイズ
`< n`
長さが
`iterable`
割り切れない
`n`
それが望ましい動作でない場合は、_fillvalue_を渡すことができ、最後のタプルの末尾を長さに埋め込むために使用されます。
`n`
.
さらに、
`groupsof`
サポート
`len`
いつ
`iterable`
サポート
`len`
.
##### 例
**ココナッツ:**
```coconut
pairs = range(1, 11) |> groupsof$(2)
```
**Python:**
```coconut_python
pairs = []
group = []
for item in range(1, 11):
group.append(item)
if len(group) == 2:
pairs.append(tuple(group))
group = []
if group:
pairs.append(tuple(group))
```
####
`windowsof`
**windowsof**(_size_, _iterable_, _fillvalue_=
`...`
、_ステップ_=
`1`
)
`windowsof`
サイズ _size_ の _iterable_ 上のスライディング ウィンドウを効果的に模倣する反復可能オブジェクトを生成します。_step_ はウィンドウ間の間隔を決定します。
_size_ が _iterable_ より大きい場合、
`windowsof`
空の反復可能オブジェクトが生成されます。これが望ましい動作でない場合は、_fillvalue_ を渡して、欠落値の代わりに使用できます。また、_fillvalue_ が渡され、_iterable_ の長さが _step_ で割り切れない場合は、_fillvalue_ を使用して最後のウィンドウも埋められます。_fillvalue_ は最後のウィンドウにのみ表示されることに注意してください。
さらに、
`windowsof`
サポート
`len`
いつ
`iterable`
サポート
`len`
.
##### 例
**ココナッツ:**
```coconut
assert "12345" |> windowsof$(3) |> list == [("1", "2", "3"), ("2", "3", "4"), ("3", "4", "5")]
```
**Python:**
_の定義なしでは実行できません
`windowsof`
; 完全な定義についてはコンパイルされたヘッダーを参照してください。_
####
`all_equal`
**すべて\_等しい**(_反復可能_、_to_=
`...`
)
ココナッツ
`all_equal`
組み込み関数は反復可能オブジェクトを受け取り、そのすべての要素が互いに等しいかどうかを判断します。
_to_ が渡された場合、
`all_equal`
すべての要素が単に互いに等しいのではなく、その値と具体的に等しいかどうかを確認します。
次の点に注意してください。
`all_equal`
等式の推移性を前提としており、
`!=`
の否定である
`==`
、そして空の配列は常にすべての要素が等しい。
[
`numpy`
](#numpy-integration) オブジェクト。
##### 例
**ココナッツ:**
```coconut
all_equal([1, 1, 1])
all_equal([1, 1, 2])
```
**Python:**
```coconut_python
sentinel = object()
def all_equal(iterable):
first_item = sentinel
for item in iterable:
if first_item is sentinel:
first_item = item
elif first_item != item:
return False
return True
all_equal([1, 1, 1])
all_equal([1, 1, 2])
```
####
`tee`
**tee**(_iterable_, _n_=
`2`
)
Coconut は、
`itertools.tee`
組み込みとして
`tee`
。
けれど
`tee`
非推奨ではない、[
`reiterable`
](#reiterable) は一般的に
`tee`
。
カスタム
`tee`
/
`reiterable`
カスタム[コンテナ/コレクション](https://docs.python.org/3/library/collections.abc.html)の実装は、
`__copy__`
メソッド。すべての[シーケンス/マッピング/セット](https://docs.python.org/3/library/collections.abc.html)は、呼び出しを行わなくても常に反復可能であると想定されることに注意してください。
`__copy__`
.
##### Python ドキュメント
**tee**(_iterable, n=2_)
単一の反復可能オブジェクトから _n_ 個の独立した反復子を返します。次と同等です:
```coconut_python
def tee(iterable, n=2):
it = iter(iterable)
deques = [collections.deque() for i in range(n)]
def gen(mydeque):
while True:
if not mydeque:
newval = next(it)
for d in deques:
d.append(newval)
yield mydeque.popleft()
return tuple(gen(d) for d in deques)
```
一度
`tee()`
分割が行われた場合、元の _iterable_ は他の場所で使用しないでください。そうしないと、_iterable_ が tee オブジェクトに通知されずに進められる可能性があります。
この itertool は、大量の補助ストレージを必要とする場合があります (一時データの保存量によって異なります)。一般に、1 つのイテレータがデータのほとんどまたはすべてを使用してから別のイテレータが開始する場合は、
`list()`
の代わりに
`tee()`
.
##### 例
**ココナッツ:**
```coconut
original, temp = tee(original)
sliced = temp$[5:]
```
**Python:**
```coconut_python
import itertools
original, temp = itertools.tee(original)
sliced = itertools.islice(temp, 5, None)
```
####
`consume`
**消費**(_iterable_, _keep\_last_=
`0`
)
ココナッツは
`consume`
関数はイテレータを効率的に使い尽くし、それに含まれる遅延評価を実行します。
`consume`
オプションの引数を1つ取り、
`keep_last`
は、デフォルトで0に設定され、末尾から何個の項目をシーケンスとして返すかを指定します(
`None`
すべての要素が保持されます)。
次と同等:
```coconut
def consume(iterable, keep_last=0):
"""Fully exhaust iterable and return the last keep_last elements."""
return collections.deque(iterable, maxlen=keep_last)
```
##### 理由
イテレータに操作を遅延適用するプロセスでは、最終的にイテレータの評価が必要になるポイントに到達します。これを効率的に行うために、Coconut は
`consume`
関数は、指定されたイテレータを完全に使い尽くします。
##### 例
**Coconut:**
```coconut
range(10) |> map$((x) => x**2) |> map$(print) |> consume
```
**Python:**
```coconut_python
collections.deque(map(print, map(lambda x: x**2, range(10))), maxlen=0)
```
### 並列化のための組み込み機能
####
`process_map`
そして
`thread_map`
##### **プロセス\_マップ**(_function_、*_iterables_、*、_chunksize_=
`1`
、_厳密_=
`False`
、_stream_=
`False`
、_注文済み_=
`True`
)
ココナッツは
`multiprocessing`
ベースのバージョン
`map`
という名前で
`process_map`
。
`process_map`
複数のプロセスを使用するため、
`map`
CPUバウンドタスクの場合。
`process_map`
、トレースバックは、遭遇するとすぐに印刷されます。結果は、_ordered_= でない限り、入力と同じ順序になります。
`False`
。
`process_map`
入力イテレータ全体をメモリにロードすることはありませんが、デフォルトでは、単一の出力が要求されるとすぐに入力イテレータ全体を消費します。反復処理中に_stream_=を渡すことで、結果を1つずつストリーミングできます。
`True`
ただし、_stream_=に注意してください
`True`
結果のイテレータは、
`process_map.multiple_sequential_calls`
ブロック(下記参照)。
なぜなら
`process_map`
実行に複数のプロセスを使用する場合、その引数はすべてピクル可能である必要があります。モジュールレベルで定義されたオブジェクトのみがピクル可能であり、ラムダ、関数内で定義されたオブジェクト、またはインタープリタ内で定義されたオブジェクトはピクル可能ではありません。さらに、Windowsでは、
`process_map`
内部で発生する
`if __name__ == "__main__"`
ガード。
`process_map`
サポート
`chunksize`
引数は、各プロセスに一度にいくつのアイテムを渡すかを決定します。非常に長い反復可能オブジェクトを扱う場合は、_chunksize_ の値を大きくすることをお勧めします。さらに、複数の反復可能オブジェクトがある場合は、_strict_ を次のように設定できます。
`True`
すべての反復可能オブジェクトが同じ長さであることを確認します。
_非推奨:
`parallel_map`
は非推奨のエイリアスとして利用可能です
`process_map`
廃止予定の機能は、
`--strict`
モード._
##### **process\_map\.multiple\_sequential\_calls**(_max\_workers_=
`None`
)
複数の連続呼び出しが
`process_map`
作成する必要がある場合は、
`with process_map.multiple_sequential_calls():`
ブロックすると、異なる呼び出しが同じプロセスプールを使用するようになり、
`process_map`
すぐにリストを返すのではなく、
`process_map`
オブジェクト。複数の連続呼び出しが必要で、process_mapの遅延処理が必要な場合は、
`process_map`
オブジェクトは、
`multiple_sequential_calls`
ブロックし、ブロック内で 1 回だけ反復します。
`process_map.multiple_sequential_calls`
プロセス数を設定するための_max\_workers_引数もサポートしています。
`max_workers=None`
、Coconut は、コール スタックの上位からワーカー プールを再利用するなど、適切な _max\_workers_ を選択します。
##### **thread\_map**(_function_, *_iterables_, *, _chunksize_=
`1`
、_厳密_=
`False`
、_stream_=
`False`
、_注文済み_=
`True`
)
##### **thread\_map\.multiple\_sequential\_calls**(_max\_workers_=
`None`
)
ココナッツは
`multithreading`
ベースのバージョンの[
`process_map`
](#process_map) という名前で
`thread_map`
。
`thread_map`
そして
`thread_map.multiple_sequential_calls`
同じように振る舞う
`process_map`
ただし、マルチプロセスではなくマルチスレッドを使用するため、CPython のグローバル インタープリタ ロックにより、主に IO バウンド タスクにのみ役立ちます。
_非推奨:
`concurrent_map`
は非推奨のエイリアスとして利用可能です
`thread_map`
廃止予定の機能は、
`--strict`
mode._
##### Python ドキュメント
**process_map**(_func, \*iterables_, _chunksize_=
`1`
)
同等
`map(func, *iterables)`
ただし、_func_ は非同期的に実行され、_func_ への複数の呼び出しが同時に行われる場合があります。呼び出しによって例外が発生した場合、その値がイテレータから取得されるときにその例外が発生します。
`process_map`
反復可能オブジェクトをいくつかのチャンクに分割し、それをプロセスプールに個別のタスクとして送信します。これらのチャンクの(おおよその)サイズは、_chunksize_ を正の整数に設定することで指定できます。非常に長い反復可能オブジェクトの場合、_chunksize_ に大きな値を使用すると、デフォルト値の _chunksize_ を使用するよりもジョブが **はるかに** 速く完了します。
`1`
.
**thread_map**(_func, \*iterables_, _chunksize_=
`1`
)
同等
`map(func, *iterables)`
ただし、_func_ は非同期的に実行され、_func_ への複数の呼び出しが同時に行われる場合があります。呼び出しによって例外が発生した場合、その値がイテレータから取得されるときにその例外が発生します。
`thread_map`
反復可能オブジェクトをいくつかのチャンクに分割し、スレッドプールに個別のタスクとして送信します。これらのチャンクの(おおよその)サイズは、_chunksize_ を正の整数に設定することで指定できます。非常に長い反復可能オブジェクトの場合、_chunksize_ に大きな値を使用すると、デフォルト値の _chunksize_ を使用するよりもジョブが **はるかに** 速く完了します。
`1`
.
##### 例
**ココナッツ:**
```coconut
process_map(pow$(2), range(100)) |> list |> print
```
**Python:**
```coconut_python
import functools
from multiprocessing import Pool
with Pool() as pool:
print(list(pool.imap(functools.partial(pow, 2), range(100))))
```
**ココナッツ:**
```coconut
thread_map(get_data_for_user, get_all_users()) |> list |> print
```
**Python:**
```coconut_python
import functools
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor() as executor:
print(list(executor.map(get_data_for_user, get_all_users())))
```
####
`collectby`
そして
`mapreduce`
##### **collectby**(_key\_func_, _iterable_, _value\_func_=
`None`
、\*、_reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_map\_using_=
`None`
)
`collectby(key_func, iterable)`
アイテムを収集する
`iterable`
キーとなるリストの辞書に
`key_func(item)`
.
_value\_func_ が渡された場合は、代わりに収集します
`value_func(item)`
各リストに
`item`
.
_reduce\_func_ が渡された場合、項目をリストに収集する代わりに、[
`reduce`
](#reduce)を_reduce\_func_で各キーの項目に対して実行し、MapReduce操作を効果的に実装します。キーが一意であることを意図している場合は、
`reduce_func=False`
(
`reduce_func=False`
_collect\_in_ が渡された場合もデフォルトです)。_reduce\_func_ が渡された場合は、_reduce\_func\_init_ も渡される可能性があり、_reduce\_func_ で削減するときの初期値を決定します。
_collect\_in_ が渡された場合は、コレクションを _collect\_in_ から初期化するのではなく、
`collections.defaultdict`
(もし
`reduce_func=None`
)または空の
`dict`
(そうでない場合)。さらに、_reduce\_func_のデフォルトは
`False`
それよりも
`None`
_collect\_in_が渡されたときに使用します。結果を
`pandas.DataFrame`
.
_map_using_ が渡された場合は計算します
`key_func`
そして
`value_func`
反復可能オブジェクトにマッピングすることで
`map_using`
として
`map`
. [ と合わせて使うと便利です
`process_map`
](#プロセスマップ)/[
`thread_map`
](#thread_map)を参照してください。
`.using_threads`
そして
`.using_processes`
簡単なショートカットメソッドについては、以下をご覧ください。
`map_using`
内部的に。
`collectby`
は[
`itertools.groupby`
](https://docs.python.org/3/library/itertools.html#itertools.groupby) ただし、
`collectby`
入力反復可能オブジェクト内の順序に関係なく共通要素を集約しますが、
`groupby`
入力反復可能オブジェクト内で隣接する共通要素のみを集約します。
##### **mapreduce**(_key\_value\_func_, _iterable_, \*, _reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_map\_using_=
`None`
)
`mapreduce(key_value_func, iterable)`
同じ機能
`collectby`
ですが、キーと値を1つの関数で計算することができます。_key\_value\_func_は2つのタプルを返す必要があります。
`(key, value)`
.
##### **collectby.using_threads**(_key\_func_, _iterable_, _value\_func_=
`None`
、\*、_reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_注文済み_=
`False`
、_チャンクサイズ_=
`1`
、_max\_workers_=
`None`
)
##### **collectby.using_processes**(_key\_func_, _iterable_, _value\_func_=
`None`
、\*、_reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_注文済み_=
`False`
、_チャンクサイズ_=
`1`
、_max\_workers_=
`None`
)
##### **mapreduce.using_threads**(_key\_value\_func_、_iterable_、\*、_reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_注文済み_=
`False`
、_チャンクサイズ_=
`1`
、_max\_workers_=
`None`
)
##### **mapreduce.using_processes**(_key\_value\_func_、_iterable_、\*、_reduce\_func_=
`None`
、_collect\_in_=
`None`
、_reduce\_func\_init_=
`...`
、_注文済み_=
`False`
、_チャンクサイズ_=
`1`
、_max\_workers_=
`None`
)
これらのショートカットメソッドは
`collectby`
/
`mapreduce`
と
`map_using`
[に設定
`process_map`
](#プロセスマップ)/[
`thread_map`
](#thread_map) は、
`.multiple_sequential_calls`
方法と
`stream=True`
[の議論
`process_map`
](#プロセスマップ)/[
`thread_map`
](#thread_map)。
`reduce_func`
結果が到着するとすぐに呼び出され、デフォルトでは到着した順序で呼び出されます(元の順序を強制するには、_ordered_=を渡します)。
`True`
)
複数の連続呼び出しを行うには
`collectby.using_threads()`
/
`mapreduce.using_threads()`
、を使用して管理します
`thread_map.multiple_sequential_calls()`
同様に、
`process_map.multiple_sequential_calls()`
管理する
`.using_processes()`
.
非常に長い反復可能オブジェクトの場合は、デフォルト以外の値を渡すことを強くお勧めします。
`1`
_chunksize_ の場合。
例として、
`mapreduce.using_processes`
実質的には以下と同等です:
```coconut
def mapreduce.using_processes(key_value_func, iterable, *, reduce_func=None, ordered=False, chunksize=1, max_workers=None):
with process_map.multiple_sequential_calls(max_workers=max_workers):
return mapreduce(
key_value_func,
iterable,
reduce_func=reduce_func,
map_using=process_map$(
stream=True,
ordered=ordered,
chunksize=chunksize,
),
)
```
##### 例
**ココナッツ:**
```coconut
user_balances = (
balance_data
|> collectby$(.user, value_func=.balance, reduce_func=(+))
)
```
**Python:**
```coconut_python
from collections import defaultdict
user_balances = defaultdict(int)
for item in balance_data:
user_balances[item.user] += item.balance
```
####
`async_map`
**async\_map**(_async\_func_、*_iters_、_strict_=
`False`
)
`async_map`
[ を使用して _async\_func_ を _iters_ に非同期的にマップします。
`anyio`
](https://anyio.readthedocs.io/en/stable/) は、_async\_func_ が機能するためにインストールする必要があります。_strict_ 関数は [
`map`
/
`zip`
](#enhanced-built-ins) により、すべての _iter_ の長さが同じになるよう強制します。
次と同等:
```coconut
async def async_map[T, U](
async_func: async T -> U,
*iters: T$[],
strict: bool = False
) -> U[]:
"""Map async_func over iters asynchronously using anyio."""
import anyio
results = []
async def store_func_in_of(i, args):
got = await async_func(*args)
results.extend([None] * (1 + i - len(results)))
results[i] = got
async with anyio.create_task_group() as nursery:
for i, args in enumerate(zip(*iters, strict=strict)):
nursery.start_soon(store_func_in_of, i, args)
return results
```
##### 例
**ココナッツ:**
```coconut
async def load_pages(urls) = (
urls
|> async_map$(load_page)
|> await
)
```
**Python:**
```coconut_python
import anyio
async def load_pages(urls):
results = [None] * len(urls)
async def proc_url(i, url):
results[i] = await load_page(url)
async with anyio.create_task_group() as nursery:
for i, url in enumerate(urls)
nursery.start_soon(proc_url, i, url)
return results
```
### 型指定の組み込み
```{contents}
---
local:
depth: 1
---
```
####
`TYPE_CHECKING`
の
`TYPE_CHECKING`
変数は次のように設定されます
`False`
実行時および
`True`
型チェック中に、
`typing`
輸入と
`TypeVar`
定義が実行時に実行されないようにする。
`typing`
輸入
`if TYPE_CHECKING:`
ブロックでは、[
`typing`
](https://docs.python.org/3/library/typing.html) モジュールをネイティブにサポートしていないPythonバージョンで使用しないでください。さらに、
`TYPE_CHECKING`
デフォルトで入力ミスしたコードを非表示にするためにも使用できます。
##### Python Docs
想定される特別な定数
`True`
サードパーティの静的型チェッカーによって。
`False`
実行時に。使用法:
```coconut_python
if TYPE_CHECKING:
import expensive_mod
def fun(arg: expensive_mod.SomeType) -> None:
local_var: expensive_mod.AnotherType = other_fun()
```
##### 例
**ココナッツ:**
```coconut
if TYPE_CHECKING:
from typing import List
x: List[str] = ["a", "b"]
```
```coconut
if TYPE_CHECKING:
def factorial(n: int) -> int: ...
else:
def factorial(0) = 1
addpattern def factorial(n) = n * factorial(n-1)
```
**Python:**
```coconut_python
try:
from typing import TYPE_CHECKING
except ImportError:
TYPE_CHECKING = False
if TYPE_CHECKING:
from typing import List
x: List[str] = ["a", "b"]
```
```coconut_python
try:
from typing import TYPE_CHECKING
except ImportError:
TYPE_CHECKING = False
if TYPE_CHECKING:
def factorial(n: int) -> int: ...
else:
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
```
####
`reveal_type`
そして
`reveal_locals`
[MyPy](#mypy-integration)などのCoconutに統合された静的型解析ツールを使用する場合、
`reveal_type(<expr>)`
MyPyは、
`<expr>`
そして
`reveal_locals()`
MyPyは現在の型を出力します
`locals()`
実行時に、
`reveal_type(x)`
は常に恒等関数であり、
`reveal_locals()`
常に返される
`None`
詳細については、[MyPy ドキュメント](https://mypy.readthedocs.io/en/stable/common_issues.html#reveal-type) を参照してください。
##### 例
**Coconut:**
```coconut_pycon
> coconut --mypy
Coconut Interpreter vX.X.X:
(enter 'exit()' or press Ctrl-D to end)
>>> reveal_type(fmap)
<function fmap at 0x00000239B06E2040>
<string>:17: note: Revealed type is 'def [_T, _U] (func: def (_T`-1) -> _U`-2, obj: typing.Iterable[_T`-1]) -> typing.Iterable[_U`-2]'
>>>
```
**パイソン**
```coconut_python
try:
from typing import TYPE_CHECKING
except ImportError:
TYPE_CHECKING = False
if not TYPE_CHECKING:
def reveal_type(x):
return x
from coconut.__coconut__ import fmap
reveal_type(fmap)
```
## ココナッツAPI
```{contents}
---
local:
depth: 2
---
```
###
`coconut.embed`
**ココナッツ.埋め込み**(_カーネル_=
`None`
、_深さ_=
`0`
、\*\*_kwargs_)
_kernel_= の場合
`False`
(デフォルト)、現在のローカル名前空間から初期化されたCoconut Jupyterコンソールを埋め込みます。_kernel_=の場合
`True`
は、ローカル名前空間から初期化された Coconut Jupyter カーネルを起動し、その後、このカーネルにアタッチできます。_depth_ は、無視する追加の呼び出しフレームの数を示します。_kwargs_ は、_kernel_ に基づいて [IPython.embed](https://ipython.readthedocs.io/en/stable/api/generated/IPython.terminal.embed.html#IPython.terminal.embed.embed) または [IPython.embed_kernel](https://ipython.readthedocs.io/en/stable/api/generated/IPython.html#IPython.embed_kernel) のようになります。
推奨される使用法は、コードが
`from coconut import embed; embed()`
を挿入すると、その時点から初期化された対話型 Coconut シェルを起動できます。
### 自動コンパイル
自動コンパイルを使用すると、最初にコンパイル手順を実行することなく、Coconut ファイルを直接インポートできます。自動コンパイルは、[
`coconut.api`
](#coconut-api) を他のものをインポートする前に実行するか、
`coconut --site-install`
.
自動コンパイルを有効にすると、Coconut は各インポートをチェックして、
`.coco`
ファイルがある場合は自動的にコンパイルします。Coconutがインポートしようとしているファイルを認識するには、次の方法でアクセスできる必要があります。
`sys.path`
通常のインポートと同様です。
自動コンパイルは常に
`--target sys --line-numbers --keep-lines`
デフォルトでは、Python 3.4以降では自動コンパイルは
`__coconut_cache__`
コンパイルされたPythonをキャッシュするディレクトリ。
`__coconut_cache__`
常に削除されます
`__file__`
.
自動コンパイルは、Coconut インタープリタまたは [
`coconut-run`
](#coconut-scripts)。Coconutインタープリタで自動コンパイルを使用する場合、渡されたコンパイルオプションも自動コンパイルに使用されます。さらに、インタープリタは常に現在の作業ディレクトリからのインポートを許可しているため、簡単にコンパイルして試すことができます。
`.coco`
Coconutインタープリタを実行してインポートするだけで、ファイルを作成できます。
Coconutインタープリタを使用する場合は、
`reload`
組み込みは常に提供されており、インポートされたモジュールを簡単に再ロード(および再コンパイル)できます。
### Coconut エンコーディング
自動コンパイルは、コンパイルされたコードをキャッシュするため、Coconut ファイルを動的にコンパイルするための推奨される方法ですが、
`.py`
再コンパイルを防ぐためのファイルに加えて、Coconutは特別な
```coconut
```
追加できる宣言
`.py`
ファイルをCoconutファイルとして扱うようにするには、このようなコーディング宣言を使用するか、
`coconut --site-install`
または
`import coconut.api`
最初にファイルをインポートする前に、
`
宣言。自動コンパイルと同様に、Coconut エンコーディングは常に Coconut インタープリターから利用できます。コンパイルでは常に [Coconut Jupyter カーネル](
`coconut.api`
自動コンパイルを有効にするだけでなく、
`coconut.api`
コマンドラインからではなくコードから Coconut コンパイラーを呼び出すためにも使用できます。さまざまな API 関数の仕様については以下を参照してください。
_非推奨:
`coconut.convenience`
は非推奨のエイリアスです
`coconut.api`
._
`get_state`
**coconut.api.get\_state**(_state_=
`None`
)
現在のコンパイルパラメータを格納する状態オブジェクトを取得します。状態オブジェクトは [**setup**](
_state_ が
`None`
は新しい状態オブジェクトを取得しますが、_state_が
`False`
グローバル状態オブジェクトが返されます。
`parse`
**coconut.api.parse**(_code_=
`""`
、_モード_=
`"sys"`
、_状態_=
`False`
、_keep\_internal\_state_=
`None`
)
おそらくAPI関数の中で最も便利なもの。
`parse`
Coconutコードを入力として受け取り、同等のコンパイル済みPythonコードを出力します。_mode_は解析のコンテキストを示すために使用され、_state_は[**get_state**](
`False`
は、グローバル状態オブジェクトを使用します)。_keep\_internal\_state_は、状態オブジェクトが内部状態([カスタム演算子](
`None`
グローバル _state_ を使用していない場合、内部状態は保持されます。
_code_ が渡されない場合、
`parse`
指定された _mode_ のヘッダーのみを出力します。これを実行すると、将来のコードをヘッダーなしで解析および実行できる実行環境を設定できます。
各 _mode_ には、使用するパーサーと先頭に追加するヘッダーの 2 つのコンポーネントがあります。パーサーは入力として許可される Coconut コードを決定し、ヘッダーはコンパイルされた Python の使用方法を決定します。_mode_ の可能な値は次のとおりです:
-
`"sys"`
: (デフォルト)
+ parser: file
* ファイルパーサーは、任意の Coconut コードを解析できます。
+ header: sys
* このヘッダーは [
`coconut.__coconut__`
](
-
`"exec"`
:
+ パーサー: ファイル
+ ヘッダー: exec
* 渡されたとき
`exec`
グローバルレベルでは、このヘッダーは必要な Coconut オブジェクトをすべてインポートするのではなく、それ自体で作成します。
-
`"file"`
:
+ パーサー: ファイル
+ ヘッダー: ファイル
* このヘッダーは、
`--standalone`
ファイルに渡されてはならない
`exec`
.
-
`"package"`
:
+ パーサー: ファイル
+ ヘッダー: パッケージ
* このヘッダーは、
`--package`
ファイルに渡されてはならない
`exec`
.
-
`"block"`
:
+ パーサー: ファイル
+ ヘッダー: なし
* ヘッダーが含まれていないため、これは
`exec`
ヘッダー付きのコードがグローバルレベルですでに実行されている場合。
-
`"single"`
:
+ パーサー: 単一
* Coconut コードの 1 行のみ解析できます。
+ ヘッダー: なし
-
`"eval"`
:
+ パーサー: eval
* ステートメントではなく、Coconut 式のみを解析できます。
+ ヘッダー: なし
-
`"lenient"`
:
+ パーサー: 寛容
* 任意の Coconut コードを解析でき、先頭の空白を許可し、末尾に改行はありません。
+ ヘッダー: なし
-
`"xonsh"`
:
+ パーサー: xonsh
* Coconut [ を解析します
`xonsh`
](https://xon.sh) [Coconut's で使用するコード
`xonsh`
サポート](#xonsh-support)。
+ ヘッダー: なし
##### 例
```coconut_python
from coconut.api import parse
exec(parse())
while True:
exec(parse(input(), mode="block"))
```
####
`setup`
**coconut.api.setup**(_target_=
`None`
、_厳密_=
`False`
、_minify_=
`False`
、_行番号_=
`True`
、_keep\_lines_=
`False`
、_no\_tco_=
`False`
、_no\_wrap_=
`False`
、*、_状態_=
`False`
)
`setup`
指定されたコンパイルパラメータを使用して、指定された状態オブジェクトを設定するために使用できます。各パラメータは、同じ名前のコマンドラインフラグに対応しています。_target_ は、次のいずれかである必要があります。
`None`
デフォルトのターゲットまたは任意の[許容ターゲット](#allowable-targets)の文字列。
_state_が
`False`
グローバル状態オブジェクトが使用されます。
####
`warm_up`
**coconut.api.warm_up**(_streamline_=
`True`
、_enable\_incremental\_mode_=
`False`
、*、_状態_=
`False`
)
オプションで、コンパイラをウォームアップして解析の準備を整えるために呼び出すことができます。_streamline_ を渡すと、ウォームアップに時間がかかりますが、解析時間が大幅に短縮されます (デフォルトでは、このレベルのウォームアップは、コンパイラが大きなファイルに遭遇した場合にのみ実行されます)。_enable\_incremental\_mode_ を渡すと、コンパイラの増分モードが有効になり、文字列を解析してから後でその文字列の続きを解析することで、パフォーマンスが大幅に向上します。
####
`cmd`
**coconut.api.cmd**(_args_=
`None`
、*、_argv_=
`None`
、_interact_=
`False`
、_default\_target_=
`None`
、_default\_jobs_=
`None`
、_状態_=
`False`
)
指定された _args_ を、
`coconut`
コマンドラインでは、_interact_がtrueまたは
`-i`
が渡されると、インタープリタは起動されません。さらに、_argv_ は次のように引数を渡すために使用できます。
`--argv`
_default\_target_はデフォルトを設定するために使用できます
`--target`
.
指定された _state_ オブジェクトにコマンドラインフラグを設定するのと同じ効果があります。
`setup`
(グローバル
`state`
_state_ が
`False`
)。
####
`cmd_sys`
**coconut.api.cmd_sys**(_args_=
`None`
、*、_argv_=
`None`
、_interact_=
`False`
、_default\_target_=
`"sys"`
、_default\_jobs_=
`"0"`
、_状態_=
`False`
)
同じ
`coconut.api.cmd`
しかし_default\_target_は
`"sys"`
それよりも
`None`
(ユニバーサル) および _default\_jobs_=
`"0"`
それよりも
`None`
(
`"sys"`
)。 以来
`cmd_sys`
デフォルトでは使用しない
`multiprocessing`
、それが問題になる可能性がある場合はいつでもそれが好まれます。たとえば、[
`if __name__ == "__main__"`
Windows でのブロック](https://stackoverflow.com/questions/20360686/compulsory-usage-of-if-name-main-in-windows-while-using-multiprocessi)。
####
`coconut_exec`
**coconut.api.coconut_exec**(_expression_, _globals_=
`None`
、_地元_=
`None`
、_状態_=
`False`
、_keep\_internal\_state_=
`None`
)
[のバージョン
`exec`
](https://docs.python.org/3/library/functions.html#exec) は、Coconut コードを実行できます。
####
`coconut_eval`
**coconut.api.coconut_eval**(_expression_, _globals_=
`None`
、_地元_=
`None`
、_状態_=
`False`
、_keep\_internal\_state_=
`None`
)
[のバージョン
`eval`
](https://docs.python.org/3/library/functions.html#eval) は、Coconut コードを評価できます。
####
`auto_compilation`
**coconut.api.auto_compilation**(_on_=
`True`
、_args_=
`None`
、_use\_cache\_dir_=
`None`
)
[自動コンパイル](#automatic-compilation)をオンまたはオフにします。この関数は、
`coconut.api`
がインポートされます。
_args_ が渡された場合、自動コンパイルに使用する Coconut コマンドライン引数が設定されます。引数は [ と同じ方法で処理されます。
`coconut-run`
](#coconut-scripts) のように
`--quiet --target sys --keep-lines`
すべてデフォルトで設定されます。
_use\_cache\_dir_ が渡された場合、
`__coconut_cache__`
コンパイルファイルをその場でコンパイルするのではなく、コンパイルファイルを置くディレクトリを指定します。
`__coconut_cache__`
常に削除されます
`__file__`
.
####
`use_coconut_breakpoint`
**coconut.api.use_coconut_breakpoint**(_on_=
`True`
)
[
`breakpoint`
Coconutが広く利用できるようにした組み込み](https://www.python.org/dev/peps/pep-0553/) [
`coconut.embed`
[ ](#coconut-embed) の代わりに
`pdb.set_trace`
](https://docs.python.org/3/library/pdb.html#pdb.set_trace) (または、
`on=False`
)。この関数は、
`coconut.api`
インポートされます。
####
`find_packages`
そして
`find_and_compile_packages`
**coconut.api.find_packages**(_where_=
`"."`
、_除外_=
`()`
、_include_=
`("*",)`
)
**coconut.api.find_and_compile_packages**(_where_=
`"."`
、_除外_=
`()`
、_include_=
`("*",)`
)
どちらの関数も [
`setuptools.find_packages`
](https://setuptools.pypa.io/en/latest/userguide/quickstart.html#package-discovery) と同じですが、Python パッケージではなく Coconut パッケージを検索する点が異なります。
`find_and_compile_packages`
さらに、見つかったCoconutパッケージをその場でコンパイルします。
これらの関数のいずれかを
`setup.py`
、含める必要があります
`coconut`
[ビルド時の依存関係として
`pyproject.toml`
](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/#build-time-dependencies)を参照してください。
`setuptools`
Coconutファイルをパッケージ化するには、以下も追加する必要があります。
`global-include *.coco`
あなたの[
`MANIFEST.in`
](https://setuptools.pypa.io/en/latest/userguide/miscellaneous.html) および [pass
`include_package_data=True`
に
`setuptools.setup`
](https://setuptools.pypa.io/en/latest/userguide/datafiles.html)。
##### 例
```coconut_python
# if you put this in your setup.py, your Coconut package will be compiled in-place whenever it is installed
from setuptools import setup
from coconut.api import find_and_compile_packages
setup(
name=...,
version=...,
packages=find_and_compile_packages(),
)
```
####
`version`
**coconut.api.version**(**[**_which_**]**)
Coconut のバージョンに関する情報を含む文字列を取得します。オプションの引数 _which_ は、必要なバージョン情報のタイプです。_which_ の可能な値は次のとおりです:
-
`"num"`
: 数値バージョン (デフォルト)
-
`"name"`
: バージョンコード名
-
`"spec"`
: コードネームが付けられた数字バージョン
-
`"tag"`
: GitHub およびドキュメント URL で使用されるバージョン タグ
-
`"-v"`
: によって印刷される完全な文字列
`coconut -v`
####
`CoconutException`
API関数でエラーが発生した場合、
`CoconutException`
インスタンスが発生する可能性があります。
`coconut.api.CoconutException`
このようなエラーをキャッチできるようにするために提供されています。
###
`coconut.__coconut__`
純粋なPythonからCoconutの組み込み関数にアクセスできると便利な場合があります。これを実現するために、Coconutは以下を提供しています。
`coconut.__coconut__`
、これはまさに
`__coconut__.py`
Coconut がパッケージモードでコンパイルされると、ヘッダーファイルが含まれます。
すべての Coconut 組み込み関数は、
`coconut.__coconut__`
インポートするには、次の方法をお勧めします。
`from coconut.__coconut__ import`
使用する組み込み関数をすべてインポートします。
##### 例
```coconut_python
from coconut.__coconut__ import process_map
```