String Haskell-IO字符串获取多行

String Haskell-IO字符串获取多行,string,list,haskell,io,String,List,Haskell,Io,我正在尝试编写一个函数,该函数获取多个字符串输入,并终止于一个空行('\n'),如下所示 getLines :: IO [String] getLines = do x <- getLine if x == "" return () else do xs <- getLines return (x:xs) getLines::IO[字符串] 这几乎是正确的 您需要在if之后添加。您可能

我正在尝试编写一个函数,该函数获取多个字符串输入,并终止于一个空行('\n'),如下所示

getLines :: IO [String]
getLines = do x <- getLine
           if x == ""
           return ()
           else do xs <- getLines
                return (x:xs)
getLines::IO[字符串]
这几乎是正确的


您需要在
if
之后添加
。您可能还需要稍微更改缩进,以便所有内容都缩进到
x
而不是
do
。我认为这应该就可以了。

您需要
然后
之后的
如果
()
(空元组)应该是
[]
(空列表)。在
if
中,如果
then
else
位于单独的行上,则它们也需要缩进,因为
if-then-else
是一个运算符,编译器需要知道表达式是否继续。您的缩进需要调整,以便所有缩进都比前面的
do
缩进得多:

getLines :: IO [String]
getLines = do x <- getLine
              if x == ""
                then return []
                else do xs <- getLines
                        return (x:xs)
getLines :: IO [String]
getLines = do
  x <- getLine
  if x == ""
    then return []
    else do
      xs <- getLines
      return (x:xs)

作为一种风格,您也可以使用
null x
而不是
x==”

它目前也不会进行打字检查,我认为
return()
应该是
return[]
<代码>[]
是一个空列表,
()
是单位。
(x:)getLines
也是可能的。从定义上看并不更好,但在本例中,我更喜欢它而不是
do
-符号。需要导入控件。Applicative(())
。@Zoidberg:是的,我通常更喜欢Applicative样式,但不想过度更改示例。它也可以被写入
getLines=untilNull getLine
,其中
untilNull
定义为无点和无空格的
execWriterT.fix.ap(liftM(=)(tell.([])).const)).const.lift
,并带有适当的导入。