使用单词的字符串列表的Haskell字符串

时间:2013-02-05 22:20:39

标签: string list haskell word

我对Haskell很新,我现在正在使用LearnYouAHaskell。 我试图将一个由空格分隔的字符串,并将其分解为一个较小的字符串列表。 我目前的计划:

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

但在这种情况下,它告诉我我有一个IO错误。 根据我的理解,getLine是一个动作,因此,由于这是不纯的,我必须将它绑定到“行”。 Line是getLine的精确表示,它是一个IO String。

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

匹配

好像line不是字符串。 此外,我可以在程序中使用:t line,当我查看它是否是正确类型的实际值时?

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

编辑:

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

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

为什么不起作用?

2 个答案:

答案 0 :(得分:7)

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

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

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

return :: Monad m => a -> m a在这种情况下,我们可以将其专门化为a -> IO a类型,然后再调整为[String] -> 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块中的有效行,它将被运行,但如果它是纯代码,它将被评估和打印。 (像这样的交互式解释器通常称为Read-Eval-Print-Loop的REPL。)

答案 1 :(得分: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);