IO
IOは難しい.....
ふつけるでアクションと説明されていて、ふむそういうものなのかと思っていたけれど、そんな特殊なものがHaskellにあるわけないだろう!
と思って記事を。
Haskellでは、すべては関数です。多分。
以前書いた、
import Control.Applicative print' :: String -> String -> IO () print' n = print.sum.map read.take (read n).words main =print' <$>getLine<*>getContents
の記事の、解決編です。
コメントで指摘をいただき、
main関数の型が、IO (IO ())になっていることがわかりました。
(<$>)の型が、
Prelude Control.Applicative> :t (<$>) (<$>) :: Functor f => (a -> b) -> f a -> f b
となっているので、まずはfunctorの型クラスのインスタンスを見てみる。
するとこいつは、
リストモナド
Maybeモナド
IOモナド
をインスタンスに持つ。
次に、getLine,getContentsの型を調べる。
getLine :: IO String getContents :: IO String
なので、これはgetLineに問題がありそうです。
Hoogle情報により
getLine same as hGetLine stdin
とのこと。
そこで、hGetLineを調べてみると、
hGetLine :: Handle -> IO String
この結果をソースコードに起き変えると、(<$>)の型は、
(<$>) :: Functor f => (Handle -> IO String) -> Handle -> IO (IO String)
になってしまうことになるのかな。
関数は全て一引数であることを踏まえると、先にgetLineの型が評価され、それに合わせて第二引数の型が決定されるんだろうから。
つまり、第二引数の型がIO Stringであるはずのところ、Handleになってしまっているので、これはつまりstdin,
よって、実際に動かしても入力を受け付けなかったと考えられる。
どういうことかというと、
getContents :: Handle -> IO Stirng
なので、getContentsが、stdinだけで評価されたということ??
解決編と思いきや、なかなかうまくいかない。
うーん、よくわからなくなってきた
それで、うまく動作しなかったんですね。