はじめに

前の記事でMaybeモナドを実現したが、そこでリストを取得したときにそれぞれに対して関数を適用して、Maybeモナドでつなげたいとする。このMaybeモナドの仕様上、流れてくる値に適用するす関数は引数を一つしか取れない。そう、カリー化が必要なのである。

実装

以下は最小の実装である。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Curry(object):
def __init__(self, f):
self.f = f
self.argv = []

def __getitem__(self, x):
if isinstance(x, tuple):
self.argv += list(x)
else:
self.argv.append(x)
return self

def __call__(self, *args):
return self.f(*self.argv, *args)

やっていることは引数を[x]が呼ばれるだけ溜め込んでいき、()で関数を実行するときに溜め込んだ引数を適用しているだけだ。

これを使うとMaybeモナドを使用してこのようなことができる。

1
print(Just([1, 2, 3])[Curry(map, 2)[lambda n:n**2]][list][sum]()) # 14

Maybeモナドの強さがお分かりいただけただろう。カリー化できるようになっただけでここまでできることが増えるである。