看着definition of getLine
in the Haskell Prelude, 我得到了递归的工作方式,你继续询问一个字符,直到你遇到一个换行符,然后你建立一个列表,然后你返回一个包含在IO中的列表。getLine如何在haskell中工作?
但是我的问题是return
声明在这种情况下是如何工作的,具体来说return (c:....:return "")
在遇到基本情况时如何工作。你如何将return ""
列入清单?
看着definition of getLine
in the Haskell Prelude, 我得到了递归的工作方式,你继续询问一个字符,直到你遇到一个换行符,然后你建立一个列表,然后你返回一个包含在IO中的列表。getLine如何在haskell中工作?
但是我的问题是return
声明在这种情况下是如何工作的,具体来说return (c:....:return "")
在遇到基本情况时如何工作。你如何将return ""
列入清单?
return
不像大多数语言那样是一种控制结构。它是一元值的构造函数。让我们来看看它的类型:
return :: Monad m => a -> m a
在这种情况下,给定一个String
值,它会产生一个IO String
值。
return
是if
的每个分支中评估的最后一个表达式并不意味着return
结束执行;其他表达可能发生在return
之后。从列表单子考虑一个简单的例子:
foo :: Int -> Int -> [Int]
foo x y = return x ++ return y
在列表单子,return
只需创建一个包含其参数一个新的单项目列表。这两个列表然后连接到函数返回的最终结果列表中。
$ return 3 :: [Int]
[3]
$ foo 3 4
[3,4]
do
-notation是语法糖。
do x <- e
rest
相当于
e >>= \x -> rest
其中>>=
是flatMap
或bind
操作(它附加回调IO
容器)。
flatMap :: IO a -> (a -> IO b) -> IO b
含义是:IO a
类型的定容器连接a -> IO b
型,当容器在其操作成功发射的回调,这会产生类型的新容器IO b
所以
getLine =
getChar >>= \c ->
if c == '\n'
then (return [])
else getLine >>= \rest ->
return (c : rest)
什么是指? getLine
立即将执行委托给getChar
IO
-container,并带有一个回调函数,用于分析传递给它的字符。如果是换行符,则执行“return ""
”,这是IO
-container的构造,立即返回空的String
。 否则,我们称自己,抓住rest
和return
当前c
字符附加到rest
。
P.S .: return
用于将纯粹的值转换为容器,因为Monad
接口不允许我们绑定非容器生成的回调(这有很好的理由)。
请记住,字符串只是字符列表,所以''“'和'[] :: [Char]'是一样的,所以在这个空列表中包含一个字符是有道理的。另外,你不直接把它放在'return'“'上。注意'c:getLine'(这没有任何意义)和'do {s < - getLine; return(c:s)}' – Alec
请注意,“”并不是任何东西。 – pdexter
你认为'return'“'是什么意思? – sepp2k