如何通过 IO 操作遍历列表

Hob*_*mok 2 io monads haskell types list-comprehension

所以我正在编写一个程序来检查 .txt 文件的每一行是否是回文,

import System.IO

main :: IO()
main = do {
content <- readFile "palindrom.txt";
print content;
print (lines content);
singleWord (head (lines content));
return ();
}

palindrom :: [Char] -> Bool
palindrom a = a == reverse a

singleWord :: [Char] -> IO()
singleWord a = do { 
print (length a);
print (show (palindrom a));
}
Run Code Online (Sandbox Code Playgroud)

但是singleWord (head (lines content))我不需要singleWord遍历整个列表。

问题是,使用map或正常的列表理解,我总是会遇到大量不同的错误lines content(应该是一个字符串数组或 IO 字符串)显然总是我不想要的类型(我试过搞乱永远有类型声明,但它一直是错误的类型,或者是正确的类型,但在额外的数组层或其他任何地方)。

我的最后一次尝试是通过递归遍历数组,并使用以下额外代码:

walkthrough [] = []
walkthrough x = do { singleWord head x; walkthrough (tail x) }
Run Code Online (Sandbox Code Playgroud)

无论如何我都无法正确类型转换。

它应该替换singleWord (head (lines content))in main,如果我尝试任何类型分类,比如

walkthrough :: [[Char]] -> [[Char]]
walkthrough [] = ["Hi"]
walkthrough x = do { singleWord head x; walkthrough (tail x) }
Run Code Online (Sandbox Code Playgroud)

我得到

Couldn't match type `IO' with `[]'
      Expected type: [()]
        Actual type: IO ()
Run Code Online (Sandbox Code Playgroud)

或其他一些无法组合在一起的东西。

Bja*_*ius 5

您正在寻找一个名为mapM_.

main :: IO ()
main = do {
  content <- readFile "palindrom.txt";
  mapM_ singleWord (lines content);
};


palindrome :: [Char] -> Bool
palindrome a = (a == reverse a)

singleWord :: [Char] -> IO()
singleWord a = do {
  let {
    adverb = (if palindrome a then " " else " not ");
  };
  putStrLn  (a ++ " is" ++ adverb ++ "a palindrome.");
};
Run Code Online (Sandbox Code Playgroud)