[英]Haskell Polymorphic definition
我無法理解fold
和foldr
之間的區別。 fold
的定義是:
fold :: (t->t->t) -> [t] -> t
fold f [a] = a
fold f (a:b:x)= f a (fold f (b:x))
其中只有一個類型參數t
foldr
定義為
foldr :: (t->u->u) -> u -> [t] -> u
foldr f s [] = s
foldr f s (a:x) = f a (foldr f s x)
我正在閱讀“函數式編程的技巧”,它說fold
函數是通過添加一個額外的參數進行修改的,目的是檢查空列表。 這是沒有意義的,為什么有必要對foldr
,當fold
功能本身可能已被修改為所有的目的。
其次,當我嘗試本書中的以下示例時:
rev :: [t] -> [t]
rev list = foldr stick [] list
stick :: t -> [t] -> [t]
stick a x = x++[a]
並將foldr
的定義修改為foldr::(t->t->t)->[t]->t
。 擁抱引發了無限統一類型的錯誤。 我嘗試使用Google搜索,但找不到滿意的答案。
因此總結一下我的疑問如下:
foldr
類型比倍比較一般。 我將從結尾開始:
rev :: [t] -> [t]
rev list = foldr stick [] list
stick :: t -> [t] -> [t]
stick a x = x ++ [a]
如果使用給定的foldr
定義,它將正常工作:
foldr :: (t->u->u) -> u -> [t] -> u
foldr f s [] = s
foldr f s (a:x) = f a (foldr f s x)
如您在這里看到的:
λ> rev [1..5]
[5,4,3,2,1]
如果用fold
定義替換它,那將行不通:
fold :: (t->t->t) -> [t] -> t
無論您如何命名,都是因為麻煩始於簽名。
看到-當你做rev list = fold stick [] list
你說
t -> t -> t
應該以某種方式等於
t' -> [t'] -> [t']
作為第一個是類型fold
預計,它的第一個參數 ,第二個是通過給定的簽名stick
(改名t
到t'
這里,表明類型應該可能會有所不同)。
現在,這將意味着,無論t ~ t'
和t ~ [t']
或t ~ [t]
這是最有可能你(順便說一句錯誤: a ~ b
這里我說兩種類型a
和b
應該是平等的 -認為=
如果您喜歡)
我希望這可以讓您有所懷疑
現在開始第一部分:說實話,我不知道該告訴你什么。
使fold
變得更通用的原因是,然后它變得更通用 -實際上foldr
是列表的一個非常特殊的功能-它是列表的變形 (另請參閱Wikipedia )
但這對於要在列表上進行操作的常規函數來說很復雜
事實上,你可以(使用空或利弊風格圖案匹配的基本遞歸的)只有重寫對列表的功能數量龐大foldr
-這很可能是你的課程的重要組成部分(我覺得你是一個學生FP101x對嗎?)和您的書-因為這是高階函數將它們全部統治 的示例 ;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.