入力をIntのリストに変換する

初歩的な部分だけど自分なりに勉強になったのでメモしとく

以下のような入力ファイルがあるとする
sample.dat

1 2 3

で、このファイルからの入力を[Int]としたいとすると以下のように書ける
sample.hs

main = do
    s <- getLine
    let ss = words s
    let ns = map read ss :: [Int]

実行は以下

$ runghc sample.hs < sample.dat

これは関数合成とファンクターの性質を使って以下のようにも書ける

main = do
   ns <- fmap (map read . words) getLine :: IO [Int]  

String->[String]であるwordsと[String]->[a]である(map read)を合成して

map read . words :: String -> [a]

という関数を作る。
さらにIO Stringはファンクターであることからfmapを使ってStringに関数を適用できる。

getLine :: IO String
fmap :: Functor f => (a -> b) -> f a -> f b
(getLineに適用したときはfがIOとなる) 

fmapの第一引数(a->b)には↑で関数合成したものを入れるのでそのときのfmapは以下のようになる

fmap :: (String -> [a]) -> IO String -> IO [a]
(getLineと(map read . words)を適用時)

最後にreadの結果をIntとして取り出したいため式全体の型を末尾に指定して最終的な形になる

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!