簡體   English   中英

Haskell文件夾會導致類型錯誤,而foldl不會

[英]Haskell foldr results in type error while foldl doesn't

我正在通過“從第一原理開始的Haskell編程”。 在“折疊列表”一章中,練習5f,

當我評估

foldr const 'a' [1..5]

我懂了

沒有(Num Char)實例產生於文字'1'的情況

但是,隨着

foldl const 'a' [1..5]

我得到'a'

我得到的褶皺都懶, foldr不穿過脊椎和foldl一樣。 但是,即使查看foldr和foldl的定義,

foldr f z []     = z 
foldr f z (x:xs) = f x (foldr f z xs) 

foldl f z []     = z                  
foldl f z (x:xs) = foldl f (f z x) xs

我不知道為什么會有這種類型的錯誤。 我猜編譯器根據zChar )的類型推斷xNum )的類型,但是我看不到它在哪里繪制連接,因為constf不需要將其兩個參數設為相同的類型。

有什么想法嗎?

好,看看文件foldr :: (a -> b -> b) -> b -> [a] -> b的類型foldr :: (a -> b -> b) -> b -> [a] -> b

從右邊開始,你顯然必須有a是一些實例NumEnum (因為你用[1..5]

接下來,您傳遞'a'這樣您就有b ~ Char

最后,你有const的功能-和const是const :: a -> b -> a -注意你怎么現在必須有a ~ b ,因為你統一

a -> b -> b
a -> b -> a
        ^^^^^

但這當然意味着'a'必須是Char不是的Num實例的值...這是您的錯誤(它抱怨1,因為從左開始是問題很明顯的地方)


foldl在另一側具有foldl :: (b -> a -> b) -> b -> [a] -> b

因此,現在您又有a Num a某個實例, b必須再次為Char但現在const就適合了(只需將ba切換為const類型)

foldlfoldr用不同順序的參數調用f 這是foldr調用const x 'a' ,但foldl調用const 'a' x 后者的結果為'a',這很好,但是后者的結果為x ,這是錯誤的,因為x是一個Int且結果應該與累加器( Char )具有相同的類型。

這是一個打字問題。 foldl的類型是

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b    

文件foldr類型為:

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

當您將foldr應用於const時,您將獲得:

foldr const :: Foldable t => b -> t b -> b

接下來,提供'a'參數,得到

(foldr const 'a') :: Foldable t => t Char -> Char

因此,當您傳遞[1..5]作為參數時,它將嘗試通過(Enum a, Num a) => [a]統一t Char Char類型是Enum類的實例,但不是Num的實例,這是您收到此錯誤消息的原因。

就像其他人所說的, foldlfoldr中參數的順序是不同的。 使用flip const代替:

> foldr (flip const) 'a' [1..5]
'a'

暫無
暫無

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

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