web-dev-qa-db-ja.com

Haskell:「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'

ヒントはありますか? mapが値ではなくリストを返すことに関係していると思いますが、これを修正する簡単な方法が見つかりませんでした。

現在、文字列のリストを出力する唯一の方法は、リストを反復して各要素を出力する関数を記述することです(リストが[a]の場合は出力しますが、(a:b)の場合は出力して再帰します)。しかし、それはmuch mapを使用する方が簡単です...

ありがとう!

52
Jay

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
_
95
Ayman Hourieh

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

20