人気ブログランキング | 話題のタグを見る

モナドでモジュール化(2)

前回の記事では、モジュールは直列にしかつなぐことができなかった。そこで、parallel 関数を追加して並列にもモジュールをつなげるようにしてみた。parallel fx fy xs 関数は、関数 fx と関数 fy とリスト xs を引数にとり、(fx xs) or (fy xs) を戻り地として返す。

-- filename: "maybe.hs"
import Data.List

multiplesOfTwo xs = if m == [] then Nothing else Just m
  where m = filter (\x -> mod x 2 == 0) xs

multiplesOfThree xs = if m == [] then Nothing else Just m
  where m = filter (\x -> mod x 3 == 0) xs

multiplesOfN n xs = if m == [] then Nothing else Just m
  where m = filter (\x -> mod x n == 0) xs

parallel fx fy xs = parallel' (fx xs) (fy xs)
  where
    parallel' Nothing Nothing = Nothing
    parallel' (Just ys) Nothing = Just ys
    parallel' Nothing (Just zs) = Just zs
    parallel' (Just ys) (Just zs) = Just (union ys zs)

parallel 関数を使うと、2の倍数または3の倍数は次のように検索できる。
*Main> parallel multiplesOfTwo multiplesOfThree [1..20]
Just [2,4,6,8,10,12,14,16,18,20,3,9,15]

また、これを利用して、2の倍数または3の倍数のうち5の倍数でもあるものは次のように計算できる。
*Main> parallel multiplesOfTwo multiplesOfThree [1..20] >>= multiplesOfN 5
Just [10,20,15]

さらに、2の倍数または3の倍数または5の倍数である数は次のようになる。
*Main> parallel (parallel multiplesOfTwo multiplesOfThree) (multiplesOfN 5) [1..20]
Just [2,4,6,8,10,12,14,16,18,20,3,9,15,5]

モナドについての詳しい理論はわからないが、操作的には、「引数1個、戻り値モナド型」の関数を単位とすると、プログラムのモジュール化が非常に容易にできるようだ。
by tnomura9 | 2011-10-06 23:13 | Haskell | Comments(0)
<< Perfume ダンスコンテスト モナドでモジュール化(1) >>