如何在Haskell IO中用空格n分隔用户输入的字符串

时间:2018-11-29 13:00:36

标签: haskell io

我想问用户一个句子,然后返回该句子,但单词要放在单独的行上。

例如,如果用户输入"hello I am tall",则计算机将返回:

hello,
I 
am
tall

我尝试从头开始,但是不知道我可以使用的功能或其他东西来尝试分隔句子。到目前为止,我的代码:

 displayWords ::IO ()
 displayWords = do putStr "Please enter a line of text"
              x <- getLine
              mapM print x

我得到了错误:

  

无法将类型[[()]”与“()”匹配

编辑:还有一件事...使用mapM_ print (words x)可以解决我想要的问题,但是有没有一种方法可以打印出不带引号的内容?

EDIT2:还有一件事...评论中的某人帮助回答了先前的编辑,但是如果我将其格式更改为

displayWords:: String -> IO Int()
displayWords s = do
     mapM_ putStrLn s
     return (length s)

我得到了错误

  

无法将类型“ Char”与“ [Char]”匹配

putStrLn为什么在这里不起作用?

2 个答案:

答案 0 :(得分:1)

您需要使用words函数将字符串拆分为单独的单词。

有人建议使用mapM_ print (words x),但是由于每个单词都是一个字符串,因此使用print会将其用引号引起来,而这并不是您想要的。所以尝试

mapM_ putStrLn (words x)

答案 1 :(得分:0)

使用mapM_

  • mapM print返回一个列表,每个元素调用print的结果,但是由于print仅返回(),因此[()]不会非常有意义。

    -- here, b = ()
    mapM :: Monad m => (a -> m b) -> [a] -> m [b]
    
  • mapM_ print放弃每次通话的结果:

    mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
    

displayWords必须是IO ()类型,并且do块的类型是其最后一条语句的类型,这就是mapM产生类型的原因错误。

另一种方法是通过添加不执行任何操作的语句来忽略mapM之类的函数的结果。

do putStr "..."
   x <- getLine
   mapM print x
   return ()