本文介绍了Haskell GHCi - 使用getContents在stdin上使用EOF字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 >>>我喜欢在Python中临时解析字符串。 s =亚当斯,约翰 ...华盛顿,乔治 ...林肯,亚伯拉罕 ...杰斐逊,托马斯 ...>>>打印\\\.join(x.split(,)[1] .replace(,) for s.strip()。split(\\\) )约翰乔治亚伯拉罕托马斯 这很好用Python解释器,但我想用Haskell / GHCi做到这一点。问题是,我无法粘贴多行字符串。我可以使用带有EOF字符的getContents,但是我只能在EOF字符关闭标准输入后执行一次操作。 Prelude> s< - getContents 前奏> s 亚当斯,约翰亚当斯,约翰\华盛顿,乔治华盛顿,乔治\林肯,亚伯拉罕林肯,亚伯拉罕\杰弗逊,托马斯杰弗逊,Thomas \\\ ^ Z Prelude> :{ Prelude | putStr $ unlines $ map((filter(`notElem`,)) Prelude | .snd。(break(==',')))$ lines s Prelude | :} 约翰乔治亚伯拉罕托马斯前奏> x< - getContents ***例外:< stdin>:hGetContents:非法操作(句柄已关闭) 有没有更好的方法可以用GHCi做这件事?注意 - 我对getContents(和一般的Haskell IO)的理解可能会严重破坏。 $ b 已更新 我会玩我收到的答案。这里有一些帮助函数,我模仿Python的引用(以结尾> ,而不是从ephemient的回答开始。 getLinesWhile ::(String - > Bool) - > IO字符串 getLinesWhile p = liftM unlines $ takeWhileM p(repeat getLine) getLines :: IO字符串 getLines = getLinesWhile(/ =\\\ ) 要在GHCi中使用AndrewC的答案 - C:\ ... \代码\haskell> ghci HereDoc.hs -XQuasiQuotes ghci>:{ * HereDoc | let s = [heredoc | * HereDoc |亚当斯,约翰 * HereDoc |华盛顿,乔治 * HereDoc |林肯,亚伯拉罕 * HereDoc | Jefferson,Thomas * HereDoc | |] * HereDoc |:} ghci> putStrLn s 亚当斯,约翰华盛顿,乔治林肯,亚伯拉罕杰弗逊,托马斯 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 if pa then liftM(a :) $ takeWhileM p mas else返回[] takeWhileM _ _ =返回[] ghci中> liftM unlines $ takeWhileM(非空)(重复getLine)亚当斯,约翰华盛顿,乔治林肯,亚伯拉罕杰弗逊,托马斯 亚当斯,约翰·华盛顿,乔治·林肯,亚伯拉罕·杰弗逊,托马斯·恩 ghci> I like to parse strings ad hoc in Python by just pasting into the interpreter.>>> s = """Adams, John... Washington,George... Lincoln,Abraham... Jefferson, Thomas... """>>> print "\n".join(x.split(",")[1].replace(" ", "") for x in s.strip().split("\n"))JohnGeorgeAbrahamThomasThis works great using the Python interpreter, but I'd like to do this with Haskell/GHCi. Problem is, I can't paste multi-line strings. I can use getContents with an EOF character, but I can only do it once since the EOF character closes stdin.Prelude> s <- getContentsPrelude> s"Adams, JohnAdams, John\nWashington,GeorgeWashington,George\nLincoln,AbrahamLincoln,Abraham\nJefferson, ThomasJefferson, Thomas\n^Z"Prelude> :{Prelude| putStr $ unlines $ map ((filter (`notElem` ", "))Prelude| . snd . (break (==','))) $ lines sPrelude| :}JohnGeorgeAbrahamThomasPrelude> x <- getContents*** Exception: <stdin>: hGetContents: illegal operation (handle is closed)Is there a better way to go about doing this with GHCi? Note - my understanding of getContents (and Haskell IO in general) is probably severely broken.UPDATEDI will be playing with the answers I have received. Here are some helper functions I made (plagiarized) that simulate Python's """ quoting (by ending with """, not starting) from ephemient's answer.getLinesWhile :: (String -> Bool) -> IO StringgetLinesWhile p = liftM unlines $ takeWhileM p (repeat getLine)getLines :: IO StringgetLines = getLinesWhile (/="\"\"\"")To use AndrewC's answer in GHCi -C:\...\code\haskell> ghci HereDoc.hs -XQuasiQuotesghci> :{*HereDoc| let s = [heredoc|*HereDoc| Adams, John*HereDoc| Washington,George*HereDoc| Lincoln,Abraham*HereDoc| Jefferson, Thomas*HereDoc| |]*HereDoc| :}ghci> putStrLn sAdams, JohnWashington,GeorgeLincoln,AbrahamJefferson, Thomasghci> :{*HereDoc| putStr $ unlines $ map ((filter (`notElem` ", "))*HereDoc| . snd . (break (==','))) $ lines s*HereDoc| :}JohnGeorgeAbrahamThomas 解决方案 getContents == hGetContents stdin. Unfortunately, hGetContents marks its handle as (semi-)closed, which means anything attempting to read from stdin ever again will fail.Does it suffice to simply read up to an empty line or some other marker, never closing 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)Adams, JohnWashington, GeorgeLincoln, AbrahamJefferson, Thomas"Adams, John\nWashington, George\nLincoln, Abraham\nJefferson, Thomas\n"ghci> 这篇关于Haskell GHCi - 使用getContents在stdin上使用EOF字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-21 03:54