【问题标题】:How to separate a user inputted string by the spaces n in Haskell IO如何在 Haskell IO 中用空格 n 分隔用户输入的字符串
【发布时间】:2018-11-29 13:00:36
【问题描述】:

我想向用户询问一个句子,然后将句子返回,但单词位于不同的行。

例如,如果用户输入"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:还有一件事...... cmets 中的某个人帮助回答了之前的编辑,但如果我将其格式更改为

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

我得到了错误

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

putStrLn 怎么在这里不起作用?

【问题讨论】:

  • 改用mapM_ print (words x)
  • 有没有办法去掉引号?
  • 去掉引号,words $ filter (/='"') x
  • 每个帖子一个问题,拜托。用新鲜的问题发新鲜的帖子不被认为是不礼貌的,不用担心;但先花一点时间尝试自己解决。 (半小时似乎不足以尝试自己解决两个后续问题。)
  • print 调用 show 来生成一个字符串值,但您已经有了字符串值,这就是您得到引号的原因。使用putStrLn 而不是print

标签: haskell io


【解决方案1】:

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

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

mapM_ putStrLn (words x)

【讨论】:

  • 谢谢,我还有一条有点相关的评论。如果我把函数从 displayWords ::IO () 改成 displayWords :: String -> IO Int, (因为我想打印出有多少个单词,所以我不需要在启动后询问用户句子代码),为什么 putStrLn 不起作用?
【解决方案2】:

使用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-block 的类型是它最后一条语句的类型,这就是mapM 导致类型错误的原因。

另一种方法是通过添加一个什么都不做的语句来忽略像mapM 这样的函数的结果。

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

【讨论】:

  • 这消除了错误,但它对我原来需要用空格分隔单词的问题没有帮助。这最终会打印字符串中的每个字符。
  • 解释和修复类型错误是我愿意回答的作业问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多