[英]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.