64

文字列のリストがあり、これを試しました:

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)の場合は印刷して繰り返します)。しかし、マップを使用する方がはるかに簡単です...

ありがとう!

4

2 に答える 2

109

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
于 2009-05-31T19:28:13.367 に答える
23

アイマンの答えは、この状況に最も理にかなっています。一般に、持っていて必要な場合は[m ()]m ()を使用しますsequence_。ここで、mを含む任意のモナドを使用できますIO

于 2009-05-31T19:32:48.597 に答える