2017-10-30 8 views
1
私が読んで、ファイル名のリストにマッピングされた「readProcess」コマンドからの出力を印刷しようとしています

HaskellのIOの文字列を入れて

files <- readProcess "ls" [] [] 
let mdList = map (\file -> do 
    md <- readProcess "mdls" [file] [] 
    return md) $ splitOn "\n" files in 
    map (\md -> putStrLn md) mdList 
putStrLn "Complete" 

私はmdListにputStrLnをマップしようとするたびに、私はこれを取得しますエラー:

Couldn't match type ‘IO String’ with ‘[Char]’ 

私はIOの文字列にputStrLnを使用するように見える多くのStackOverflowの回答を読みましたが、私はそうすることができません。また、私はハスケルに新しいので、他のヒントもありがとうございます。

+4

「IO String」値は**ではなく**文字列です。あなたが料理本を食べたくないのと同じ理由で、 'IO String'を置くことは理にかなっていません。 – leftaroundabout

+0

IO文字列が文字列ではないことを認識しています。私はIO Stringを書く方法を尋ねています。 – genghiskhan

+0

あなたは 'forM_'を望みます。あなたはモナドを理解していないのであなたの問題が発生しました。最初にモナドが何であるかを理解しようとするのがよいでしょう。 – HuStmpHrrr

答えて

3
あなたは

map :: (a -> IO b) -> [a] -> [IO b] 

最終的な結果に特化した

map :: (a -> b) -> [a] -> [b] 

を使用している

は、[IO b]は、私たちが必要とするものではありません。これは、IOアクションのリストであり、すなわち実行されていない引数なし​​命令関数のリストと同等である。 代わりに、[IO b]の代わりにIO [b]になるbのリストである単一IOアクションが必要です。

ライブラリは、そのだけでなく提供:

for :: [a] -> (a -> IO b) -> IO [b] 
for_ :: [a] -> (a -> IO b) -> IO() 
:我々は結果

を集める気にしない場合は、

mapM :: (a -> IO b) -> [a] -> IO [b] 

をやライブラリも反転した引数で変異体を提供する

mapM_ :: (a -> IO b) -> [a] -> IO() 

元のコードは次のように修正できます:

import Data.Foldable 

files <- readProcess "ls" [] [] 
for_ files $ \file -> do 
    md <- readProcess "mdls" [file] [] 
    putStrLn md 
putStrLn "Complete"