簡體   English   中英

Haskell多態定義

[英]Haskell Polymorphic definition

我無法理解foldfoldr之間的區別。 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搜索,但找不到滿意的答案。

因此總結一下我的疑問如下:

  • doubt1:之所以提出了foldr類型比倍比較一般。
  • 疑問2:為什么我會得到一個錯誤,即無限統一類型。

我將從結尾開始:

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 (改名tt'這里,表明類型應該可能會有所不同)。

現在,這將意味着,無論t ~ t't ~ [t']t ~ [t]這是最有可能你(順便說一句錯誤: a ~ b這里我說兩種類型ab應該是平等的 -認為=如果您喜歡)

我希望這可以讓您有所懷疑


現在開始第一部分:說實話,我不知道該告訴你什么。

使fold變得更通用的原因是,然后它變得更通用 -實際上foldr是列表的一個非常特殊的功能-它是列表的變形 (另請參閱Wikipedia

但這對於要在列表上進行操作的常規函數​​來說復雜

事實上,你可以(使用空或利弊風格圖案匹配的基本遞歸的)只有重寫對列表的功能數量龐大foldr -這很可能是你的課程的重要組成部分(我覺得你是一個學生FP101x對嗎?)和您的書-因為這是高階函數將它們全部統治 的示例 ;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM