getLine如何在haskell中工作?

时间:2016-08-01 16:08:37

标签: haskell io functional-programming getline

definition of getLine in the Haskell Prelude, 我知道递归是如何工作的,你在那里一直要求一个字符,直到你找到一个换行符,然后你建立一个列表,然后你将它包装在一个IO中。

但是我的问题是return语句在这种情况下是如何工作的,特别是当你遇到基本情况时return (c:....:return "")如何工作。你如何将return ""列入名单?

2 个答案:

答案 0 :(得分:5)

return不是像大多数语言一样的控制结构。它是monadic值的构造函数。我们来看看它的类型:

return :: Monad m => a -> m a

在这种情况下,给定String值,它会产生IO String值。

returnif的每个分支中评估的最后一个表达式并不意味着return结束执行的事实;其他表达式可能return之后发生。从列表monad中考虑这个简单的例子:

foo :: Int -> Int -> [Int]
foo x y = return x ++ return y

在monad列表中,return只创建一个包含其参数的新单项列表。然后将这两个列表连接到函数返回的最终结果列表中。

$ return 3 :: [Int]
[3]
$ foo 3 4
[3,4]

答案 1 :(得分:0)

do - 符号是一种语法糖。

do x <- e
   rest

相当于

e >>= \x -> rest

其中>>=flatMapbind操作(它将回调附加到IO容器)。

flatMap :: IO a -> (a -> IO b) -> IO b含义是:给定类型IO a的容器附加类型为a -> IO b的回调,当容器成功运行时触发,这会生成一个类型为{{1的新容器}}

所以

IO b

意味着什么? getLine = getChar >>= \c -> if c == '\n' then (return []) else getLine >>= \rest -> return (c : rest) 立即将执行委托给getLine getChar - 容器,并带有回调,该回调分析传递给它的字符。如果是换行符,它会&#34; IO&#34;,这是return "" - 容器的构造,立即返回空IO。 否则,我们会打电话给自己,抓住String附加的restreturn当前c字符。

PS:rest用于将纯值转换为容器,因为return接口不允许我们绑定非容器产生的回调(这有很好的理由) )。