06 高階函數(shù)

所謂高階函數(shù)庶弃,就是將函數(shù)對象作為函數(shù)的參數(shù)或者函數(shù)的返回值蝎困,高階函數(shù)是抽象必不可少的工具

柯里化和部分函數(shù)

函數(shù)其實(shí)只接受一個參數(shù)

如果我說:Haskell 中仲义,函數(shù)本質(zhì)上只接受一個參數(shù)。你肯定會問:多參數(shù)函數(shù)怎么辦呢氏身?這時候高階函數(shù)就出場了寒屯!

對于多參數(shù)函數(shù)荐捻,接受一個參數(shù)后,會返回一個接受剩余參數(shù)的函數(shù)寡夹,這就是柯里化处面。

比如常見的 max 函數(shù),其類型

max :: (Ord a) => a -> a -> a

相當(dāng)于菩掏,接受一個參數(shù)魂角,返回另外一個接受一個參數(shù)的函數(shù)

max :: (Ord a) => a -> (a -> a)

ghci> max 4 5
5

相當(dāng)于

ghci> (max 4) 5
5

代碼中 (max 4) 生成了一個接受一個參數(shù)的部分函數(shù)。

部分參數(shù)生成部分函數(shù)

我們?nèi)绻貌糠謪?shù)調(diào)用函數(shù)智绸,就會得到一個部分函數(shù)野揪,所謂部分函數(shù),就是指這個函數(shù)可以接受剩余的參數(shù)

注意:已經(jīng)接受的參數(shù)作為狀態(tài)被保存在了返回的部分函數(shù)中

--定義一個接收三個參數(shù)的函數(shù)
multThree :: (Num a) => a -> a -> a -> a
multThree x y z = x * y * z

--傳入一個參數(shù)瞧栗,返回一個接收兩個參數(shù)的函數(shù)
ghci> let multTwoWithNine = multThree 9
ghci> multTwoWithNine 2 3
54

--繼續(xù)傳入一個參數(shù)斯稳,返回一個接受一個參數(shù)的函數(shù)
ghci> let multWithEighteen = multTwoWithNine 2
ghci> multWithEighteen 10
180

消除等號兩邊相同的變量可以得到部分函數(shù)

比如要定義一個和 100 比較大小的函數(shù),傳統(tǒng)方式是這樣:

compareWithHundred :: (Num a, Ord a) => a -> Ordering
compareWithHundred x = compare 100 x

注意到定義兩邊都有變量 x迹恐,就像數(shù)學(xué)中等式變換一樣挣惰,可以將等號兩邊的 x 消除,這樣就得到了一個部分函數(shù)殴边。

這個函數(shù)和上面函數(shù)的類型是完全相同的

compareWithHundred :: (Num a, Ord a) => a -> Ordering
compareWithHundred = compare 100

中綴函數(shù)生成部分函數(shù)

中綴函數(shù)生成部分函數(shù)需要用括號括起來通熄,比如

divideByTen :: (Floating a) => a -> a
divideByTen = (/10)

調(diào)用 divideByTen 200 就是 (/10) 200,和 200 / 10 等價找都。

參數(shù)的位置

因?yàn)?Haskell 是靜態(tài)類型的,因此參數(shù)的位置一般都是很明確的廊酣,不需要考慮太多

比如能耻,檢查字符是否為大寫的函數(shù)可以簡化為

isUpperAlphanum :: Char -> Bool
isUpperAlphanum = (`elem` ['A'..'Z'])

- 是個例外

這里減號 - 是個例外,因?yàn)樗拓?fù)號相同,因此需要使用函數(shù)名 subtract

柯里化生成的部分函數(shù)不是 Show 的成員

和普通函數(shù)不同晓猛,通過部分調(diào)用生成的部分函數(shù)不能在交互式環(huán)境中顯示饿幅,因?yàn)樗皇?Show 的成員

高階函數(shù)

首先看看以函數(shù)作為參數(shù)的高階函數(shù),比如接受一個函數(shù)作為參數(shù)并調(diào)用它兩次

applyTwice :: (a -> a) -> a -> a  
applyTwice f x = f (f x)

注意看它的類型聲明戒职,第一個參數(shù)是一個函數(shù)類型

因?yàn)榭吕锘梢苑浅H菀椎膭?chuàng)建函數(shù)栗恩,因此部分函數(shù)和高階函數(shù)很容易結(jié)合使用,非常強(qiáng)大

ghci> applyTwice (+3) 10  
16  

ghci> applyTwice (++ " HAHA") "HEY"  
"HEY HAHA HAHA"  

ghci> applyTwice ("HAHA " ++) "HEY"  
"HAHA HAHA HEY"  

ghci> applyTwice (multThree 2 2) 9  
144  

ghci> applyTwice (3:) [1]  
[3,3,1]

zipWith 函數(shù)

前面我們用過 zip 函數(shù)洪燥,其將兩個列表中的元素組合為序?qū)Α?/p>

下面我們來實(shí)現(xiàn)一個 zipWith 高階函數(shù)磕秤,他也是將兩個列表中的元素經(jīng)過一定的處理后,合并成一個列表捧韵,但處理方法是作為參數(shù)傳進(jìn)去的

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
--任意一個列表為空則返回空
zipWith' _ [] _ = []  
zipWith' _ _ [] = []  

zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

zipWith 結(jié)合部分函數(shù)市咆,傳入不同的處理函數(shù),可以玩出很多花樣

ghci> zipWith' (+) [4,2,5,6] [2,6,2,3]  
[6,8,7,9]  

ghci> zipWith' max [6,3,2,1] [7,3,1,5]  
[7,3,2,5]  

ghci> zipWith' (++) ["foo "再来,"bar "蒙兰,"baz "] ["fighters","hoppers"芒篷,"aldrin"]  
["foo fighters","bar hoppers","baz aldrin"] 

ghci> zipWith' (*) (replicate 5 2) [1..]  
[2,4,6,8,10]  

ghci> zipWith' (zipWith' (*)) [[1,2,3],[3,5,6],[2,3,4]] [[3,2,2],[3,4,5],[5,4,3]]  
[[3,4,6],[9,20,30],[10,12,12]]

flip 函數(shù)

flip 函數(shù)接受一個函數(shù)作參數(shù)搜变,并回傳一個相似的函數(shù),只是將兩個參數(shù)的順序倒了個

下面的代碼就是將這個問題描述了一遍:

  • 定義了一個 g 函數(shù)针炉,其返回值就是用顛倒的順序調(diào)用 f 函數(shù)
  • 最后將 g 函數(shù)返回
flip' :: (a -> b -> c) -> (b -> a -> c)  
flip' f = g  
    where g x y = f y x

數(shù)學(xué)等式又來了:消除中間變量 g 函數(shù)挠他,可以進(jìn)一步簡化代碼

再加上參數(shù)定義,這個函數(shù)就可以直接使用了

flip' :: (a -> b -> c) -> b -> a -> c  
flip' f y x = f x y

調(diào)用一下

ghci> flip' zip [1,2,3,4,5] "hello"  
[('h',1),('e',2),('l',3),('l',4),('o',5)] 

ghci> zipWith (flip' div) [2,2..] [10,8,6,4,2]  
[5,4,3,2,1]

map 與 filter

map 函數(shù)就是列表變換

map :: (a -> b) -> [a] -> [b]  
map _ [] = []  
map f (x:xs) = f x : map f xs

map 函數(shù)有非常多的用法

ghci> map (+3) [1,5,3,1,6]  
[4,8,6,4,9]  

ghci> map (++ "!") ["BIFF"糊识,"BANG"绩社,"POW"]  
["BIFF!","BANG!","POW!"]  

ghci> map (replicate 3) [3..6]  
[[3,3,3],[4,4,4],[5,5,5],[6,6,6]]  

ghci> map (map (^2)) [[1,2],[3,4,5,6],[7,8]]  
[[1,4],[9,16,25,36],[49,64]]  

ghci> map fst [(1,2),(3,5),(6,3),(2,6),(2,5)]  
[1,3,6,2,2]

map 的大部分用法都可以用列表解析來代替

filter 函數(shù),過濾列表

filter :: (a -> Bool) -> [a] -> [a]  
filter _ [] = []  
filter p (x:xs)   
    | p x       = x : filter p xs  
    | otherwise = filter p xs

使用方法

ghci> filter (>3) [1,5,3,2,1,6,4,3,2,1]  
[5,6,4]  

ghci> filter (==3) [1,2,3,4,5]  
[3]  

ghci> filter even [1..10]  
[2,4,6,8,10]  

ghci> let notNull x = not (null x) in filter notNull [[1,2,3],[],[3,4,5],[2,2],[],[],[]]  
[[1,2,3],[3,4,5],[2,2]]  

ghci> filter (`elem` ['a'..'z']) "u LaUgH aT mE BeCaUsE I aM diFfeRent"  
"uagameasadifeent" 

ghci> filter (`elem` ['A'..'Z']) "i lauGh At You BecAuse u r aLL the Same"  
"GAYBALLS"

注意:filter 的功能也可以用列表解析實(shí)現(xiàn)赂苗,特別是多條件過濾的情況下愉耙,用 filter 就比較啰嗦了

之前的快速排序使用列表解析進(jìn)行過濾的,這里把他改成用 filter 過濾拌滋,代碼如下

quicksort :: (Ord a) => [a] -> [a]    
quicksort [] = []    
quicksort (x:xs) =     
    let smallerSorted = quicksort (filter (<=x) xs)
        biggerSorted = quicksort (filter (>x) xs)   
    in  smallerSorted ++ [x] ++ biggerSorted

takeWhile 函數(shù)

從一個列表中取出符合條件的項(xiàng)朴沿,組成一個新列表。比如“找出所有小于 10000 且為奇數(shù)的平方數(shù)的和”

ghci> sum (takeWhile (<10000) (filter odd (map (^2) [1..])))  
166650

當(dāng)然败砂,也可以用列表解析實(shí)現(xiàn)

ghci> sum (takeWhile (<10000) [m | m <- [n^2 | n <- [1..]], odd m])  
166650

Collatz 串行

算法:

  • 取一個自然數(shù)赌渣,若為偶數(shù)就除以 2
    ;若為奇數(shù)就乘以 3 再加 1
  • 再用相同的方式處理所得的結(jié)果昌犹,循環(huán)得到一組數(shù)字構(gòu)成的的鏈
  • 無論任何以任何數(shù)字開始坚芜,最終的結(jié)果都會歸 1

問題:以 1 到 100 之間的所有數(shù)作為起始數(shù),會有多少個鏈的長度大于 15?

下面是生成鏈串的函數(shù)

--生成鏈串的函數(shù)
chain :: (Integral a) => a -> [a]  
chain 1 = [1]  
chain n  
    | even n =  n:chain (n `div` 2)  
    | odd n  =  n:chain (n*3 + 1)

調(diào)用效果如下

ghci> chain 10  
[10,5,16,8,4,2,1]  

ghci> chain 1  
[1]  

ghci> chain 30  
[30,15,46,23,70,35,106,53,160,80,40,20,10,5,16,8,4,2,1]

下面是過濾函數(shù)

--生成一個列表斜姥,里面的項(xiàng)都是長度大于 15 的串鏈
numLongChains :: Int  
numLongChains = length (filter isLong (map chain [1..100]))  
    where isLong xs = length xs > 15

map 的其他用法

一般情況下使用 map 鸿竖,列表中的項(xiàng)作為參數(shù)沧竟,正好符合處理函數(shù)需要,處理后的數(shù)據(jù)組成了新的列表缚忧,比如

map (*2) [0..]

有的時候悟泵,僅僅列表中的項(xiàng)作為參數(shù),比處理函數(shù)需要的參數(shù)數(shù)目要少闪水,這樣得到的就不是轉(zhuǎn)換后數(shù)據(jù)的列表糕非,而是部分函數(shù)的列表。比如: map (*) [0..] 得到的結(jié)果為 [(0*),(1*),(2*)..]

ghci> let listOfFuns = map (*) [0..]  
ghci> (listOfFuns !! 4) 5  
20

lambda

lambda 就是匿名函數(shù)球榆,可以省略函數(shù)名稱的定義朽肥,例如前面過濾 Collatz 串的函數(shù),其中的過濾條件函數(shù)可以用匿名函數(shù)替代

numLongChains :: Int  
numLongChains = length (filter (\xs -> length xs > 15) (map chain [1..100]))

用部分函數(shù)代替匿名函數(shù)

看看下面的代碼芜果,等式兩邊都有變量 x鞠呈,我們自然而然想到了柯里化。

大部分用到匿名函數(shù)的地方都可以用部分函數(shù)代替右钾,代碼更簡潔

map (\x -> x+3) [1,6,3,2]

//替換成

map (+3) [1,6,3,2]

參數(shù)相關(guān)問題

匿名函數(shù)也可以有多個參數(shù)

ghci> zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]  
[153.0,61.5,31.0,15.75,6.6]

也可以使用模式匹配蚁吝,但是無法使用多種模式

ghci> map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]  
[3,8,9,8,7]

結(jié)合柯里化和匿名函數(shù)理解函數(shù)的定義

  1. 函數(shù)的定義本質(zhì)上可以看做是給一個匿名函數(shù)對象起一個名字
  2. 由于柯里化,匿名函數(shù)也可以看做是只接受一個參數(shù)的函數(shù)

下面兩段代碼是等價的

addThree :: (Num a) => a -> a -> a -> a  
addThree x y z = x + y + z

addThree :: (Num a) => a -> a -> a -> a  
addThree = \x -> \y -> \z -> x + y + z

利用匿名函數(shù)讓 flip 函數(shù)根據(jù)可讀性

flip' :: (a -> b -> c) -> b -> a -> c  
flip' f = \x y -> f y x

折疊

折疊函數(shù)接受三個參數(shù)

  • 一個歸約函數(shù)舀射,接受兩個參數(shù):歸約值和列表的當(dāng)前項(xiàng)
  • 歸約初值
  • 一個列表

lfold 函數(shù):左折疊

用左折疊函數(shù)定義一個求和函數(shù)

sum' :: (Num a) => [a] -> a  
sum' xs = foldl (\acc x -> acc + x) 0 xs

注意:左折疊的規(guī)約函數(shù)的參數(shù)順序是:歸約值窘茁,列表的當(dāng)前項(xiàng)

前面說過,大部分匿名函數(shù)都可以用部分函數(shù)代替脆烟,改寫代碼如下山林,非常的簡潔

sum' :: (Num a) => [a] -> a  
sum' = foldl (+) 0

再用左折疊實(shí)現(xiàn)一個 elem 函數(shù),這里想演示的是邢羔,初值怎么選取

注意:這里的實(shí)現(xiàn)效率不高驼抹,因?yàn)樗谡业搅四繕?biāo)元素后,仍然繼續(xù)遍歷后面的元素

elem' :: (Eq a) => a -> [a] -> Bool  
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys

rfold 函數(shù):右折疊

右折疊和左折疊類似拜鹤,歸約函數(shù)的參數(shù)順序和左折疊相反

用右折疊實(shí)現(xiàn)一個 map 函數(shù)

map' :: (a -> b) -> [a] -> [b]  
map' f xs = foldr (\x acc -> f x : acc) [] xs

用左折疊也能實(shí)現(xiàn) map 函數(shù)框冀,但是得使用 ++ 連接符,性能較差敏簿,因此生成新 List 的時候人們一般都是使用右折疊明也。

map' f xs = foldl (\acc x -> acc ++ [f x]) [] xs

左折疊和右折疊最大的區(qū)別

  • 右折疊可以處理無限長度的數(shù)據(jù)結(jié)構(gòu),而左折疊不可以
  • 將無限 List 從中斷開執(zhí)行左折疊是可以的惯裕,不過若是向右温数,就永遠(yuǎn)到不了頭了

foldl1 與 foldr1

foldlfoldr 相似,只是他們假定 List 的首(或尾)元素作為起始值

注意:這里 foldl1foldr1 折疊的 List 中至少要有一個元素蜻势,若使用空 List 就會產(chǎn)生一個運(yùn)行時錯誤

為了體會 fold 的威力撑刺,我們就用它實(shí)現(xiàn)幾個庫函數(shù):

maximum' :: (Ord a) => [a] -> a  
maximum' = foldr1 (\x acc -> if x > acc then x else acc)  

reverse' :: [a] -> [a]  
reverse' = foldl (\acc x -> x : acc) []  

product' :: (Num a) => [a] -> a  
product' = foldr1 (*)  

filter' :: (a -> Bool) -> [a] -> [a]  
filter' p = foldr (\x acc -> if p x then x : acc else acc) []  

head' :: [a] -> a  
head' = foldr1 (\x _ -> x)  

last' :: [a] -> a  
last' = foldl1 (\_ x -> x)

scanl 和 scanr

foldlfoldr 相似,只是它們會記錄下累加值的所有狀態(tài)到一個 List握玛。也有 scanl1scanr1

ghci> scanl (+) 0 [3,5,2,1]  
[0,3,8,10,11] 

ghci> scanr (+) 0 [3,5,2,1]  
[11,8,3,1,0]  

ghci> scanl1 (\acc x -> if x > acc then x else acc) [3,4,5,3,7,9,2,1]  
[3,4,5,5,7,9,9,9]  

ghci> scanl (flip (:)) [] [3,2,1]  
[[],[3],[2,3],[1,2,3]]

優(yōu)先級提升符號 $

$ 符號相當(dāng)于為其后的表達(dá)式加了一個括號猜煮,改變優(yōu)先級次员,例如

sum (map sqrt [1..130])
sum $ map sqrt [1..130]

sqrt (3+4+9)
sqrt $ 3+4+9

f (g (z x)) 
f $ g $ z x 

sum (filter (> 10) (map (*2) [2..10])  
sum $ filter (> 10) $ map (*2) [2..10]

此外,用 $ 符號修飾的數(shù)據(jù)可以調(diào)用函數(shù)王带,這個功能在 map 中常用

ghci> map ($ 3) [(4+),(10*),(^2),sqrt]  
[7.0,30.0,9.0,1.7320508075688772]

組合函數(shù)

組合函數(shù)和數(shù)學(xué)上的組合函數(shù)類似,將幾個函數(shù)合成一個函數(shù)市殷,定義如下

(.) :: (b -> c) -> (a -> b) -> a -> c  
f . g = \x -> f (g x)

有了組合函數(shù)愕撰,部分使用匿名函數(shù)的情況可以簡化代碼,例如:將列表中的數(shù)值全部轉(zhuǎn)換成負(fù)數(shù)

ghci> map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]

改為使用組合函數(shù)

ghci> map (negate . abs) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]

再比如

ghci> map (\xs -> negate (sum (tail xs))) [[1..5],[3..6],[1..7]]  
[-14,-15,-27]

可以改為:

ghci> map (negate . sum . tail) [[1..5],[3..6],[1..7]]  
[-14,-15,-27]

多參數(shù)函數(shù)的組合

組合多參數(shù)函數(shù)時醋寝,需要使用括號或者美元符號

sum (replicate 5 (max 6.7 8.9))

可以重寫為

(sum . replicate 5 . max 6.7) 8.9

sum . replicate 5 . max 6.7 $ 8.9

在最后一個參數(shù)之前加美元符號搞挣,在其他函數(shù)之間加點(diǎn)號,這里是另外一個例子音羞;

replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))

可以改為

replicate 100 . product . map (*3) . zipWith max [1,2,3,4,5] $ [4,5,6,7,8]

函數(shù)組合可以讓柯里化更容易

下面的函數(shù)等號兩邊都有 x 囱桨,但是要想柯里化卻不是很容易

fn x = ceiling (negate (tan (cos (max 50 x))))

使用函數(shù)組合后,就很容易柯里化了

fn = ceiling . negate . tan . cos . max 50

不要炫代碼

函數(shù)組合嗅绰、部分函數(shù)非成岢Γ酷,但是有時候會導(dǎo)致代碼難以理解窘面,因此盡量寫讓人容易理解的代碼翠语,比如之前“求了小于 10000 的所有奇數(shù)的平方的和”的例子

oddSquareSum :: Integer  
oddSquareSum = sum (takeWhile (<10000) (filter odd (map (^2) [1..])))

用函數(shù)組合修改為如下代碼,一般人不容易理解

oddSquareSum :: Integer  
oddSquareSum = sum . takeWhile (<10000) . filter odd . map (^2) $ [1..]

若是給別人看财边,我可能就這么寫了:

oddSquareSum :: Integer  
oddSquareSum =   
    let oddSquares = filter odd $ map (^2) [1..]  
        belowLimit = takeWhile (<10000) oddSquares  
    in  sum belowLimit
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肌括,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子酣难,更是在濱河造成了極大的恐慌谍夭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憨募,死亡現(xiàn)場離奇詭異紧索,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)馋嗜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門齐板,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人葛菇,你說我怎么就攤上這事甘磨。” “怎么了眯停?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵济舆,是天一觀的道長。 經(jīng)常有香客問我莺债,道長滋觉,這世上最難降的妖魔是什么签夭? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮椎侠,結(jié)果婚禮上第租,老公的妹妹穿的比我還像新娘。我一直安慰自己我纪,他們只是感情好慎宾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浅悉,像睡著了一般趟据。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上术健,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天汹碱,我揣著相機(jī)與錄音,去河邊找鬼荞估。 笑死咳促,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泼舱。 我是一名探鬼主播等缀,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娇昙!你這毒婦竟也來了尺迂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤冒掌,失蹤者是張志新(化名)和其女友劉穎噪裕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體股毫,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膳音,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铃诬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祭陷。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖趣席,靈堂內(nèi)的尸體忽然破棺而出兵志,到底是詐尸還是另有隱情,我是刑警寧澤宣肚,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布想罕,位于F島的核電站,受9級特大地震影響霉涨,放射性物質(zhì)發(fā)生泄漏按价。R本人自食惡果不足惜惭适,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望楼镐。 院中可真熱鬧癞志,春花似錦、人聲如沸框产。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茅信。三九已至,卻和暖如春墓臭,著一層夾襖步出監(jiān)牢的瞬間蘸鲸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工窿锉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酌摇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓嗡载,卻偏偏與公主長得像窑多,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洼滚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容