2016-08-01 23 views
0

看着definition of getLine in the Haskell Prelude, 我得到了递归的工作方式,你继续询问一个字符,直到你遇到一个换行符,然后你建立一个列表,然后你返回一个包含在IO中的列表。getLine如何在haskell中工作?

但是我的问题是return声明在这种情况下是如何工作的,具体来说return (c:....:return "")在遇到基本情况时如何工作。你如何将return ""列入清单?

+0

请记住,字符串只是字符列表,所以''“'和'[] :: [Char]'是一样的,所以在这个空列表中包含一个字符是有道理的。另外,你不直接把它放在'return'“'上。注意'c:getLine'(这没有任何意义)和'do {s < - getLine; return(c:s)}' – Alec

+0

请注意,“”并不是任何东西。 – pdexter

+3

你认为'return'“'是什么意思? – sepp2k

回答

5

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

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

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

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

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

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

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

do -notation是语法糖。

do x <- e 
    rest 

相当于

e >>= \x -> rest 

其中>>=flatMapbind操作(它附加回调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立即将执行委托给getCharIO -container,并带有一个回调函数,用于分析传递给它的字符。如果是换行符,则执行“return ""”,这是IO -container的构造,立即返回空的String。 否则,我们称自己,抓住restreturn当前c字符附加到rest

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