【问题标题】:Haskell String to List of Strings using WordsHaskell字符串到使用单词的字符串列表
【发布时间】:2013-01-21 00:05:59
【问题描述】:

我对 Haskell 比较陌生,目前正在使用 LearnYouAHaskell。 我正在尝试获取一个由空格分隔的字符串,并将其分解为一个较小的字符串列表。 我目前的计划:

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    words line;

但在这种情况下,它告诉我我遇到了 IO 错误。 据我了解,getLine 是一个动作,所以由于这是不纯的,我必须将它绑定到“line”。 Line 是 getLine 的准确表示,它是一个 IO String。

但是,line 不应该是字符串吗? 当我尝试在线使用单词时,它告诉我 “无法将预期类型“IO a0”与实际类型 [String] 匹配

好像 line 不是字符串。 此外,我可以在程序本身中使用 :t 行来查看它是否是正确的类型吗?

我为这个新手问题道歉,但我有点卡住了。

编辑:

我在 GHCI 中做了类似的事情,它告诉我我的类型实际上是一个普通的字符串。我不明白。

Prelude> line <- getLine
"Hello fellows"
Prelude> :t line
line :: String
Prelude> words line
["Hello","fellows"]

为什么这不起作用?

【问题讨论】:

  • 错误解释:words line 的类型为 [String],但对于某些类型 a0,do 块中的所有语句都应具有类型 IO a0

标签: string list haskell word


【解决方案1】:

在haskell中如果你想返回一个值,你必须这么说:

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    return (words line)

words line 不是 IO 操作,它是一个字符串列表,因此它不能是 do 块中的语句。

return :: Monad m =&gt; a -&gt; m a,在这种情况下,我们可以将其专门化为a -&gt; IO a,然后专门化为[String] -&gt; IO [String]do 块中的每个语句都必须是 IO 语句。


更进一步:

如果你想编译你的程序,你应该有main :: IO(),这意味着你不应该返回你的列表。

例如,如果您想将这些字符串 process 转换为单个字符串然后输出,您可以这样做

process :: [String] -> String
process xss = "I don't know, some answer"

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    putStrLn (process (words line))

虽然我个人会将最后一行写成putStrLn $ process.words $ line


您在 GHCi 中的互动

Prelude> line <- getLine
"Hello fellows"
Prelude> :t line
line :: String
Prelude> words line
["Hello","fellows"]

正在使用 GHCi 实际上不只是在 IO monad 中运行的事实。在 GHCi 中,如果您的输入是 do 块中的有效行,它将运行,但如果它是纯代码,它将被评估和打印。 (这样的交互式解释器通常称为 REPL for Read-Eval-Print-Loop。)

【讨论】:

  • 感谢您的简洁解释!
  • @Noc 不客气。您是否在 GHCi 上看到了带有信息的编辑?现在不是那么简洁,但希望对您有所帮助。
【解决方案2】:

好吧,问题是你想用words line做什么?

words line 作为 do 块内的一行什么都不做,但要让它工作,您必须使用 return 将其包装在 IO monad 中:

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    return (words line);

无论如何,也许您想打印它?

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    print (words line);

【讨论】:

  • 嗯,最终的目的是做一个猪拉丁语转换器——它是用于家庭作业的,但由于这不是纯粹与之相关的东西,所以我按原样发布了它。我想获取一个输入字符串,使用 words 函数将字符串分解为单个单词。检查它是否以元音开头;做一个检查它的功能。使用 maps 和 pig Latin 函数,然后使用 unwords 将其转回字符串。
  • 那...在进一步阅读后,我意识到我不知道 return 在 Haskell 中做了什么。我完全爱上了免责声明:“你已经使用过 C、Java 或 Python 等命令式语言,你可能认为你知道这个 return 的作用,你很可能已经跳过了这个很长的段落。好吧,这里是事情:Haskell 中的 return 与大多数其他语言中的 return 完全不同!"
猜你喜欢
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 2011-05-18
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多