Haskell で IO をつなげて [a -> IO a] -> IO a 的なこと
Haskell でこういう関数が欲しいことがある:
connect :: Monad m => [a -> m a] -> a -> m a
-- 気分的には
connect (f0:f1:..) n = do
p0 <- f0 n
p1 <- f1 p0
..
fn pn
具体的にはこういうこと
printAndMultiply :: Int -> Int -> IO Int
printAndMultiply n m = do
print m
return (n*m)
main = do
n <- connect [printAndMultiply 2, printAndMultiply 3] 6
putStrLn "______"
print n
で出力が
6
12
______
36
とりあえず Hoogle に訊いてみよう. [a -> m a] -> a -> m a
このへんがそれっぽい?
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
というわけで例えばこう書くことができる
import Control.Monad
import Data.List (foldl')
printAndMultiply :: Int -> Int -> IO Int
printAndMultiply n m = do
print m
return (n*m)
f = printAndMultiply
fs :: [Int -> IO Int]
fs = [f 2, f 3, f 5, f 1, f 2]
connect :: (Monad m) => [a -> m a] -> a -> m a
connect = foldl' (>=>) return
main = do
nn <- connect fs 4
print "__"
print nn
出力
4
8
24
120
120
"__"
240
なんだけどこれでいいのかなあ.なんかもうちょっと綺麗な書き方があるような気がするんですよね.
あと Functor
とか Applicative
とかで上手いことできないのだろうか.このへん慣れ親しみかけているところなのでまだよくわかりません.