简体   繁体   English

getLine在Haskell中如何工作?

[英]How does getLine work in haskell?

Looking at the definition of getLine in the Haskell Prelude , I get how the recursion works, where you keep asking for a character until you hit a newline and you buildup a list which you then return wrapped in an IO. 查看Haskell Prelude中getLine定义 ,我了解了递归的工作方式,在这里您一直要求一个字符,直到您按下换行符,然后建立一个列表,然后将其包装在IO中。

However my question is how do the return statements work in this case, specifically how does return (c:....:return "") work when you hit the base case. 但是我的问题是在这种情况下return语句如何工作,特别是当您遇到基本情况时return (c:....:return "")工作。 How do you cons a return "" on to a list? 您如何将return ""保留在列表上?

return isn't a control structure like in most languages. return不是像大多数语言中那样的控制结构。 It's a constructor for monadic values. 它是一元数值的构造函数。 Let's take a look at its type: 让我们看一下它的类型:

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

In this case, given a String value, it produces a IO String value. 在这种情况下,给定一个String值,它将产生一个IO String值。

The fact that return is the last expression evaluated in each branch of the if doesn't mean return ends execution; returnif每个分支中最后求值的表达式,这并不意味着return终止执行。 other expressions could occur after return . return之后可能会出现其他表达式。 Consider this simple example from the list monad: 考虑清单monad中的以下简单示例:

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

In the list monad, return simply creates a new single-item list containing its argument. 在单子列表中, return简单地创建一个包含其参数的新单项列表。 Those two lists are then concatenated into the final result list returned by the function. 然后将这两个列表串联到该函数返回的最终结果列表中。

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

do -notation is a syntax sugar. do -notation是语法糖。

do x <- e
   rest

is equivalent to 相当于

e >>= \x -> rest

where >>= is a flatMap or bind operation (it attaches a callback to IO container). >>=flatMapbind操作(它将回调附加到IO容器)。

flatMap :: IO a -> (a -> IO b) -> IO b meaning is: given container of type IO a attach a callback of type a -> IO b , fired when container succeeds in its operation, and this produces a new container of type IO b flatMap :: IO a -> (a -> IO b) -> IO b含义是:给定类型IO a容器,附加一个类型a -> IO b的回调,当容器操作成功时触发,并产生一个IO b类型的新容器

So 所以

getLine =
    getChar >>= \c ->
        if c == '\n'
        then (return [])
        else getLine >>= \rest ->
             return (c : rest)

What is means? 什么意思 getLine immediately delegates execution to getChar IO -container, with a callback, which analyses the character passed to it. getLine立即通过回调将执行委派给getChar IO getChar ,该回调分析传递给它的字符。 If its a newline, it does " return "" ", which is a construction of IO -container, returning empty String immediately. 如果它是一个换行符,但它“ return "" ”,这是一个建筑IO -container,返回空String马上。 Otherwise, we call ourselves, grab the rest and return current c haracter attached to rest . 否则,我们称自己,抓住restreturn当前c连接到haracter rest

PS: return is used to turn a pure value into container, since Monad interface doesn't allow us to bind non-container-producing callbacks (there are very good reasons for this). PS: return用于将纯值转换为容器,因为Monad接口不允许我们绑定非容器产生的回调(这有很好的理由)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM