「バインド」操作のみを使用して、 Scheme(またはPython)map
および関数と同等のリストモナドを実行する方法を知っています。filter
説明するScalaは次のとおりです。
scala> // map
scala> List(1,2,3,4,5,6).flatMap {x => List(x * x)}
res20: List[Int] = List(1, 4, 9, 16, 25, 36)
scala> // filter
scala> List(1,2,3,4,5,6).flatMap {x => if (x % 2 == 0) List() else List(x)}
res21: List[Int] = List(1, 3, 5)
そしてHaskellでも同じことが言えます:
Prelude> -- map
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> [x * x])
[1,4,9,16,25,36]
Prelude> -- filter
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> if (mod x 2 == 0) then [] else [x])
[1,3,5]
SchemeとPythonには、reduce
とでグループ化されることが多い関数もmap
ありfilter
ます。このreduce
関数は、提供されたバイナリ関数を使用してリストの最初の2つの要素を結合し、次にその結果を次の要素に結合し、以下同様に続きます。値のリストの合計または積を計算するための一般的な使用法。説明するPythonを次に示します。
>>> reduce(lambda x, y: x + y, [1,2,3,4,5,6])
21
>>> (((((1+2)+3)+4)+5)+6)
21
reduce
リストモナドのバインド操作だけを使用してこれと同等の方法はありますか?bindがそれ自体でこれを実行できない場合、この操作を実行するための最も「モナディック」な方法は何ですか?
可能であれば、do
回答するときは、構文糖衣の使用を制限/回避してください(つまり、Haskellの表記法またはScalaのシーケンス内包表記)。