ブロックを表現
関数型言語Cleanでは、以下のように、局所的な関数を定義できる。
関数定義 where [局所関数定義]
Cleanの
// Clean add_square a b = a2 + b2 where a2 = a*a b2 = b*b
は、Pythonでは以下のように表現できる。
>>> lambda a, b: [a2+b2 ... for a2 in [a*a] ... for b2 in [b*b] ... ][0] <function <lambda> at 0x00E5A970> >>> _(1, 2) 5
Cleanでwhereはネストできる。
// Clean add_square a b = c where c = a2 + b2 where a2 = a*a b2 = b*b
Pythonでは、以下のようにネスト可能。
>>> lambda a, b: [c ... for c in [a2+b2 for a2 in [a*a] for b2 in [b*b]] ... ][0] <function <lambda> at 0x00E5A970> >>> _(1, 2) 5
これを並列に並べると以下のようになる。
>>> lambda a, b: [c ... for a2 in [a*a] ... for b2 in [b*b] ... for c in [a2+b2] ... ][0] <function <lambda> at 0x00E5A970> >>> _(1, 2) 5
一般的に、{式1, 式2, ..., 式n} で値として式nを持つブロックは、以下のように表現できる。上記の例のように、inの後の式でネストしても、forをフラットに並べても読みやすい方をとれば良い。また、ガードはifで表現する。
[(式1, 式2, ..., 式n,) for ローカル変数1 in [式] if 式 for ローカル変数2 in [式] if 式 ... ][0][-1]
パラメータを付けたい、もしくは遅延評価したい場合、以下のようにlambda式にする。
{|引数1, 引数2, ...| 式1, 式2, ..., 式n}
を表現すると以下の通り。
lambda 引数1, 引数2, ...: [(式1, 式2, ..., 式n,) for ローカル変数1 in [式] if 式 for ローカル変数2 in [式] if 式 ... ][0][-1]
追記(2008/3/16):
ifの意味は、関数型言語のガードとちょっと意味が違うかも。もう少し考えるつもり。