2009-05-31 10 views
50

私は文字列のリストを持っていて、これを試しました:Haskell: "putStrLn map"を使うことはできませんか?

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]ならば印刷しますが、 b))。しかし、マップを使うだけではるかにになります...

ありがとう!

答えて

89

main関数のタイプは、IO ttは型変数)である必要があります。 map putStrLn lsのタイプは[IO()]です。このエラーメッセージが表示されるのはなぜですか。あなたはghciに次のように実行することにより、この自分自身を確認することができます。問題へ

Prelude> :type map putStrLn ls 
map putStrLn ls :: [IO()] 

一つの解決策は、mapの「モナド」バージョンである、mapMを使用しています。またはmapMと同じmapM_を使用できますが、関数から返された値は収集されません。戻り値がputStrLnではないので、mapM_を使用する方が適切です。 mapM_は、次のような種類があります。ここでは

mapM_ :: Monad m => (a -> m b) -> [a] -> m() 

をそれを使用する方法である:

ls = [ "banana", "mango", "orange" ] 
main = mapM_ putStrLn ls 
+15

私がもっと早く多くのことを学びたいと思っていたことは、Data.Traversableに別のmapMが定義されていることでした。このmapMは、マップや配列などのリストに加えて、より多くのデータ構造を処理します。 –

+5

私はいつも 'main'は' IO() '型でなければならないと考えていました。 IO t 'である。それは毎日新しい何かを学ぶ方法を示しています:-) –

19

アイマンの答えは、このような状況のために最も理にかなっています。一般に、[m()]があり、m()が必要な場合は、sequence_を使用してください。mは、IOを含むいずれのモナドでもかまいません。

関連する問題