另一個 Haskell 教程/勘誤
| Haskell | |
|---|---|
| |
| 另一個 Haskell 教程 | |
| 前言 | |
| 簡介 | |
| 入門 | |
| 語言基礎 (解決方案) | |
| 型別基礎 (解決方案) | |
| IO (解決方案) | |
| 模組 (解決方案) | |
| 高階語言 (解決方案) | |
| 高階型別 (解決方案) | |
| 單子 (解決方案) | |
| 高階 IO | |
| 遞迴 | |
| 複雜度 | |
此頁面包含迄今為止在 YAHT 的 PDF 版本 中發現的勘誤列表(其中一些可能已經在 線上 HTML 版本 中更正 - (匯入))。
- 練習 3.1:“我們已經看到乘法比除法繫結得更緊密。” - 就我而言,乘法和除法具有相同的優先順序,因此它們繫結得同樣緊密。也許你的意思是加法與乘法或乘法與冪?我看到它已經在線上版本中修復了。
- 練習 7.1 的解決方案在第 79 頁的“7.3 部分應用”下存在錯誤(請參閱 高階語言:部分應用,以獲取已更正的相應 HTML 版本),練習陳述如下
| 練習 |
|---|
|
如果可能,將以下函式轉換為無點風格。 [...] func5 f l = foldr (\x y -> f (y,x)) 0 l |
- 第 81 頁的文字指出
“我們建立一個值,稱之為 x,它的值為 Red。然後我們將其應用於 colorToRGB。我們檢查是否可以將 x 與 Red “匹配”。此匹配失敗,因為根據 Eq Color 的定義,Red 不等於 Yellow。”
顯然,前提是錯誤的,初始值 x 應該是 'Yellow',以便段落的其餘部分有意義。
- 根據 PDF 檔案 的第 172 頁,解決方案陳述如下
[...] func5 = foldr (uncurry $ flip f) 0
但是,正如 Michael Mossey 在 Haskell-Beginners 郵件列表中 指出的那樣,該解決方案實際上是錯誤的。
這是正確的解決方案
[...] func5 = flip foldr 0 . flip . curry
作為旁註,Daniel Fischer 已 提供 了使用型別驗證解決方案正確性的簡潔方法,如下所示
檢查結果是否正常的一種簡單方法是
示例
Prelude> :t flip foldr 0 . flip. curry
flip foldr 0 . flip. curry :: (Num c) => ((c, b) -> c) -> [b] -> c
Prelude> :t \f list -> foldr (\x y -> f (y,x)) 0 list
\f list -> foldr (\x y -> f (y,x)) 0 list :: (Num b) =>
((b, a) -> b) -> [a] -> b
Prelude> :t \f -> foldr (uncurry $ flip f) 0
\f -> foldr (uncurry $ flip f) 0 :: (Num b1) =>
(b -> a -> b1 -> b1) -> [(a, b)] -> b1
因此,您會看到您的結果具有正確的型別,而 Hal 的結果沒有。
在上述描述中,前兩行中的第一對顯示了
flip foldr 0 . flip. curry
(即,要驗證的解決方案)的型別是
(Num c) => ((c, b) -> c) -> [b] -> c
第二對兩行顯示了
\f list -> foldr (\x y -> f (y,x)) 0 list
(即,本質上是練習中給出的表示式,即 f l = foldr (\x y -> f (y,x)) 0 l)的型別也是
(Num b) => ((b, a) -> b) -> [a] -> b
(請注意,這與上面的型別相同,只是使用重新命名變數編寫。)
第三對兩行顯示了
\f -> foldr (uncurry $ flip f) 0
(即,Hal 在教程的 PDF 版本 中給出的解決方案)的型別是
(Num b1) => (b -> a -> b1 -> b1) -> [(a, b)] -> b1
這是一個不同的型別。因此,Hal 給出的解決方案是錯誤的。
注意
(感謝 Michael Mossey 和 Daniel Fischer 在 Haskell-Beginners 郵件列表中就這個問題進行的討論。)
-- Benjamin L. Russell
2. 練習 4.11
| 練習 |
|---|
| 4.11. 測試 CPS 風格的 fold 是否模擬 foldr 或 foldl 中的任何一個。如果不是,區別在哪裡? |
它沒有指定“CPS 風格的 fold”函式,因此讀者應該假設練習是關於先前定義的 cfold
cfold’ f z [] = z cfold’ f z (x:xs) = f x z (\y -> cfold’ f y xs) cfold f z l = cfold’ (\x t g -> f x (g t)) z l
但 YAHT 中給出的解決方案實際上不是關於這個函式。事實上,這個函式的行為與 foldr 完全一樣。該解決方案是關於一個非常相似的函式:唯一的區別是 cfold' 的第二個情況中引數的順序,即
cfold' f z (x:xs) = f z x (\y -> cfold' f y xs)
YAHT 從未經過全面校對,因此這只是一個部分列表。 |
這仍在進行中。請隨時根據需要進行新增! |
