2013-04-03 68 views
1

我想写得到多个字符串输入,并终止在一个空行(“\ n”)的函数我有以下Haskell- IO字符串获得多行

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

失败编译说有有毛病的if语句

理想我想对这样的

getLines工作

苹果

(进入被按下)

输出: [ “苹果”, “鸟”, “猫”]

回答

6

if()(空元组)应该是[](空列表)之后,您需要then。在if中,thenelse需要缩进,因为if then else是一个运算符,编译器需要知道表达式是否继续。你的压痕需要进行调整,以使所有东西都要缩比领先do更多:

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

或者一切都缩进超过包含领先do线

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

作为的问题样式,您也可以使用null x而不是x == ""

+0

谢谢!它现在有效! – lopezrican304 2013-04-03 21:26:51

+1

'(x :) <$> getLines'也是可能的。根据定义,这不是更好,但在这种情况下,我更喜欢它比'做'符号。需要'输入Control.Applicative((<$>))',但。 – 2013-04-04 00:51:44

+1

@Zoidberg:是的,我通常更喜欢应用风格,但不想过度改变这个例子。它也可以写成'getLines = untilNull getLine',其中'untilNull'被定义为无空格且无空格为'execWriterT.fix.ap(liftM(= <<)(ap(unless.null).ap(liftM(>>) (tell。(:[])))。const))。const.lift'与适当的导入。 – 2013-04-04 02:53:51

1

这几乎是正确的。

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

+1

它现在也不会检测,我认为'return()'应该是'return []'。 '[]'是一个空列表,'()'是单元。 – DarkOtter 2013-04-03 21:06:52

+0

@DarkOtter是的 - 好的工作! – MathematicalOrchid 2013-04-04 07:37:04