另一個 Haskell 教程/語言進階/解答
外觀
< 另一個 Haskell 教程 | 語言進階
| Haskell | |
|---|---|
| |
| 另一個 Haskell 教程 | |
| 前言 | |
| 簡介 | |
| 入門 | |
| 語言基礎 (解答) | |
| 型別基礎 (解答) | |
| IO (解答) | |
| 模組 (解答) | |
| 高階語言 (解答) | |
| 高階型別 (解答) | |
| 單子 (解答) | |
| 高階 IO | |
| 遞迴 | |
| 複雜度 | |
函式 func3 無法轉換為無點風格。其他看起來像
func1 x = map (*x) func2 f g = filter f . map g func4 = map (+2) . filter (`elem` [1..10]) . (5:) func5 = flip foldr 0 . flip . curry
你可能很想嘗試將 func2 編寫為 filter f . map,試圖透過 eta-reduction 去除 g。在這種情況下,這是不可能的。這是因為函式組合運算子 (.) 的型別為 (b -> c) -> (a -> b) -> (a -> c)。在這種情況下,我們試圖將 map 用作第二個引數。但是 map 接受兩個引數,而 (.) 期望一個只接受一個引數的函式。
我們可以從一個遞迴定義開始
and [] = True and (x:xs) = x && and xs
從這裡,我們可以很清楚地將它改寫為
and = foldr (&&) True
我們可以遞迴地寫成
concatMap f [] = [] concatMap f (x:xs) = f x ++ concatMap f xs
這暗示著我們可以寫成
concatMap f = foldr (\a b -> f a ++ b) []
現在,我們可以進行點消除,得到
foldr (\a b -> f a ++ b) [] ==> foldr (\a b -> (++) (f a) b) [] ==> foldr (\a -> (++) (f a)) [] ==> foldr (\a -> ((++) . f) a) [] ==> foldr ((++) . f) []
