Haskell Put IO String
Я пытаюсь прочитать и распечатать вывод команды "readProcess", сопоставленной со списком имен файлов:
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"
Каждый раз, когда я пытаюсь отобразить putStrLn на mdList, я получаю эту ошибку:
Couldn't match type ‘IO String’ with ‘[Char]’
Я прочитал много ответов Stackru, которые, кажется, просто используют putStrLn для строки ввода-вывода, но я не могу это сделать. Кроме того, я новичок в Haskell, поэтому любые другие советы также приветствуются.
1 ответ
Ты используешь
map :: (a -> b) -> [a] -> [b]
который специализируется на
map :: (a -> IO b) -> [a] -> [IO b]
Конечный результат, [IO b]
это не то, что нам нужно. Это список IO
действия, то есть эквивалент списка невыполненных императивных функций без аргументов. Вместо этого мы хотим один IO
действие, результатом которого является список b
: это было бы IO [b]
вместо [IO b]
,
Библиотека также обеспечивает это:
mapM :: (a -> IO b) -> [a] -> IO [b]
или, если мы не заботимся о сборе результатов
mapM_ :: (a -> IO b) -> [a] -> IO ()
Библиотека также предоставляет варианты с перевернутыми аргументами:
for :: [a] -> (a -> IO b) -> IO [b]
for_ :: [a] -> (a -> IO b) -> IO ()
Итак, исходный код можно исправить следующим образом:
import Data.Foldable
files <- readProcess "ls" [] []
for_ files $ \file -> do
md <- readProcess "mdls" [file] []
putStrLn md
putStrLn "Complete"