IOアクション
IOアクションは実行されると副作用を含む動作を行い結果を返す。結果に返すべきものがない場合、()
空のタプル、Unitを返す。
ghci> :t putStrLn putStrLn :: String -> IO () ghci> :t putStrLn "Hello World" putStrLn "Hello World" :: IO ()
のように、putStrLnは文字列を受け取り、副作用を伴う動作を行いUnitを返す。という定義と読める。
IOアクションはmainという名前をつけてプログラムを起動すると実行される。
main = putStrLn "hello, world"
IOアクションをまとめる
IOアクションまとめてをmainに名前付けするにはdo構文を使用する。
main = do putStrLn "What's your name?" name <- getLine putStrLn $ "Hey" ++ name ++ ", you rock!"
getLine
getLineは副作用がある動作を行いStringを返す。上の例では<-
で返されたStringをname
に束縛している。
ghci> :t getLine getLine :: IO String
IOアクション
は副作用のある世界に出向き、何かを持って帰ってくる箱と表現されている。
IOアクションそのものを引数にとるのではなく、IOアクションから値を取り出し引数に与えることで、値を引数にとる関数は副作用のない純粋性を保てる。
IOアクションとlet
<-
IOアクションから返された結果を束縛、let
は純粋な式の結果を束縛する。
import Data.Char main = do putStrLn "What's your first name?" firstName <- getLine putStrLn "What's your last name?" lastName <- getLine let bigFirstName = map toUpper firstName bigLastName = map toUpper lastName putStrLn $ "Hey" ++ bigFirstName ++ " " ++ bigLastName ++ ", how are you?"
return
Haskellのreturn
はIOアクションを返す。以下の例ではgetLineで入力せずEnterキーを押した場合、mainにIO ()が返されプログラムが終了する。
main = do line <- getLine if null line then return () else do putStrLn $ reverseWords line main reverseWords :: String -> String reverseWords = unwords . map reverse . words
つまり以下で、returnが返すIOアクションの結果を束縛するという記述になる。
main = do name <- return "Mike"
when関数
when関数はif then elseのelseを省略したような動作を行う。1つ目の引数がTrueの時、2つ目の引数に渡されたIOアクションを返す。
import Control.Monad main = do input <- getLine when (input == "match") $ putStrLn input
sequence関数
sequence関数はIOアクションのリストを受け取り順に実行するIOアクションを返す。
main = do rs <- sequence [getLine, getLine] print rs
mapM mapM_ 関数
mapM関数はIOアクションを返す関数を引数にとり、シーケンスを返す。mapM_ はIOアクションの結果を捨てる。
mapM_ print [1,2,3]
forever関数
forever関数はIOアクションを受け取りそのIOアクションを永遠に繰り返す。
import Control.Monad import Data.Char main = forever $ do putStr "Give me some input: " l <- getLine putStrLn $ map toUpper l
forM関数
forMはmapMの引数順序が逆のパターン。メソッド記述が末尾にくることにより、IOアクションを返すメソッドをラムダで記述することができる。
main = do colors <- forM [1,2,3,4] $ \a -> do putStrLn $ "Which color do you associate with the number " ++ show a ++ "?" color <- getLine return color putStrLn "The colors that you associate with 1, 2, 3 and 4 are: " mapM putStrLn color