如何创建一个Haskell函数,将IO String转换为IO [String]?

7
我已经开始学习Haskell,感到有些不知所措。现在我正在尝试创建一个函数,该函数可以从标准输入或文件列表中的内容返回字符串。
换句话说,我正在尝试复制Unix wc实用程序的行为,当没有给出文件时,它会从stdin获取输入。
我创建了类似于以下内容的代码:
parseArgs [] = [getContents]
parseArgs fs = mapM readFile fs

但是它不能编译,因为在某些情况下我有一个 [IO String] 和在另外一种情况下是 IO [String]。我无法使这个 pattern matching 在所有情况下返回 IO [String]。请指导我正确的方向。

1个回答

7
为了使第一个模式也是 IO [String],您需要先从列表中解包值,然后重新封装。类似这样的内容:
do c <- getContents
   return [c]

在正常的单子符号中:

getContents >>= \c -> return [c]

在这种情况下,通常最好使用一个函数对象而不是一个单子。这样你就可以避免使用return
fmap (:[]) getContents

(:[])的意思与\x -> [x]相同,它创建一个只包含一个元素的列表。


6
既然 [] 本身就是一个(应用)函子和单子,因此你也可以使用 fmap return getContents 或者在 Control.Applicative 中使用 return <$> getContents。 (或者您可以将任何一个 return 替换为 pure,同样使用 Control.Applicative。) - Antal Spector-Zabusky
我不知道那是可能的。谢谢你的提示。 - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接