ハスケル:「map putStrLn」は使えないのでしょうか?
質問
文字列のリストがあり、これを試しました:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
それはうまくいきませんでしたが、その理由がわかりません。
ghc print-list.hs
print-list.hs:3:0:
Couldn't match expected type `IO t' against inferred type `[IO ()]'
In the expression: main
When checking the type of the function `main'
ヒントはありますか?これはマップが値ではなくリストを返すことに関係していると思いますが、これを修正する簡単な方法は見つかりませんでした。
現時点で私が知っている文字列のリストを出力する唯一の方法は、リストを反復して各要素を出力する関数を書くことです (リストが [a] の場合は出力しますが、(a:b) の場合は出力して再帰します)。しかし、それはそうだろう 多くの マップを使用するだけの方が簡単です...
ありがとう!
解決
の種類 main
関数はこうあるべきです IO t
(どこ t
は型変数です)。の種類 map putStrLn ls
は [IO ()]
. 。これが、このエラー メッセージが表示される理由です。これを自分で確認するには、次のコマンドを実行します。 ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
問題に対する 1 つの解決策は、 mapM
, 、これはの「モナディック」バージョンです map
. 。または、使用できます mapM_
それは同じです mapM
ただし、関数からの戻り値は収集しません。戻り値は気にしないので、 putStrLn
, を使用する方が適切です。 mapM_
ここ。 mapM_
には次のタイプがあります。
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
使用方法は次のとおりです。
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
他のヒント
アイマンの答えは、このような状況のための最も理にかなっています。あなたは[m ()]
を持っていて、m ()
をしたい場合は一般的に、そしてsequence_
はm
を含む任意のモナドできIO
を使用します。
所属していません StackOverflow