gpt4 book ai didi

Haskell GHCi - 在标准输入上使用 EOF 字符和 getContents

转载 作者:行者123 更新时间:2023-12-04 14:31:44 25 4
gpt4 key购买 nike

我喜欢通过粘贴到解释器中来临时解析 Python 中的字符串。

>>> s = """Adams, John
... Washington,George
... Lincoln,Abraham
... Jefferson, Thomas
... """
>>> print "\n".join(x.split(",")[1].replace(" ", "")
for x in s.strip().split("\n"))
John
George
Abraham
Thomas

这在使用 Python 解释器时效果很好,但我想用 Haskell/GHCi 来做这件事。问题是,我不能粘贴多行字符串。我可以将 getContents 与 EOF 字符一起使用,但我只能执行一次,因为 EOF 字符会关闭标准输入。
Prelude> s <- getContents
Prelude> s
"Adams, John
Adams, John\nWashington,George
Washington,George\nLincoln,Abraham
Lincoln,Abraham\nJefferson, Thomas
Jefferson, Thomas\n^Z
"
Prelude> :{
Prelude| putStr $ unlines $ map ((filter (`notElem` ", "))
Prelude| . snd . (break (==','))) $ lines s
Prelude| :}
John
George
Abraham
Thomas
Prelude> x <- getContents
*** Exception: <stdin>: hGetContents: illegal operation (handle is closed)

有没有更好的方法来用 GHCi 做到这一点?注意 - 我对 getContents (以及一般的 Haskell IO)的理解可能被严重破坏。

更新

我会玩弄我收到的答案。以下是我制作(抄袭)的一些辅助函数,它们模拟 Python 的 """从 ehemient 的回答中引用(以 """ 结尾,而不是开始)。
getLinesWhile :: (String -> Bool) -> IO String
getLinesWhile p = liftM unlines $ takeWhileM p (repeat getLine)

getLines :: IO String
getLines = getLinesWhile (/="\"\"\"")

要在 GHCi 中使用 AndrewC 的答案 -
C:\...\code\haskell> ghci HereDoc.hs -XQuasiQuotes
ghci> :{
*HereDoc| let s = [heredoc|
*HereDoc| Adams, John
*HereDoc| Washington,George
*HereDoc| Lincoln,Abraham
*HereDoc| Jefferson, Thomas
*HereDoc| |]
*HereDoc| :}
ghci> putStrLn s
Adams, John
Washington,George
Lincoln,Abraham
Jefferson, Thomas
ghci> :{
*HereDoc| putStr $ unlines $ map ((filter (`notElem` ", "))
*HereDoc| . snd . (break (==','))) $ lines s
*HereDoc| :}
John
George
Abraham
Thomas

最佳答案

getContents == hGetContents stdin .不幸的是,hGetContents将其句柄标记为(半)关闭,这意味着任何试图从 stdin 读取的内容将再次失败。

只需读取一个空行或其他标记就足够了,从不关闭stdin ?

takeWhileM :: Monad m => (a -> Bool) -> [m a] -> m [a]
takeWhileM p (ma : mas) = do
a <- ma
if p a
then liftM (a :) $ takeWhileM p mas
else return []
takeWhileM _ _ = return []

ghci> liftM unlines $ takeWhileM (not . null) (repeat getLine)
亚当斯,约翰
华盛顿,乔治
林肯,亚伯拉罕
杰斐逊,托马斯

"亚当斯,约翰\n华盛顿,乔治\n林肯,亚伯拉罕\n杰斐逊,托马斯\n"
ghci>

关于Haskell GHCi - 在标准输入上使用 EOF 字符和 getContents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12119420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com