[英]How does getLine work in haskell?
查看Haskell Prelude中getLine
的定义 ,我了解了递归的工作方式,在这里您一直要求一个字符,直到您按下换行符,然后建立一个列表,然后将其包装在IO中。
但是我的问题是在这种情况下return
语句如何工作,特别是当您遇到基本情况时return (c:....:return "")
工作。 您如何将return ""
保留在列表上?
return
不是像大多数语言中那样的控制结构。 它是一元数值的构造函数。 让我们看一下它的类型:
return :: Monad m => a -> m a
在这种情况下,给定一个String
值,它将产生一个IO String
值。
return
是if
每个分支中最后求值的表达式,这并不意味着return
终止执行。 return
之后可能会出现其他表达式。 考虑清单monad中的以下简单示例:
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
getChar
,该回调分析传递给它的字符。 如果它是一个换行符,但它“ return ""
”,这是一个建筑IO
-container,返回空String
马上。 否则,我们称自己,抓住rest
和return
当前c
连接到haracter rest
。
PS: return
用于将纯值转换为容器,因为Monad
接口不允许我们绑定非容器产生的回调(这有很好的理由)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.