簡體   English   中英

使用文件夾在Haskell中定義地圖,

[英]Use foldr to define map in Haskell,

我是Haskell的新手,並嘗試了解map函數。

到目前為止,我了解以下內容。

map::(a->b)->[a]->[b]
map f (x:xs) = f x : map f xs

但我不理解以下定義:使用文件定義地圖

map'::(a->b)->[a]->[b]
map' f = foldr ( (:).f ) []

誰能解釋以上地圖的定義以及為什么與地圖相同

讓我們看看foldr的來源

foldr k z = go where
    go []     = z
    go (x:xs) = k x (go xs)

現在,讓我們將map的定義與go的定義進行比較:

map f []     = []
map f (x:xs) = f x : map f xs

看起來很相似,不是嗎? 讓我們重寫第二個子句,以提取將x與遞歸調用的結果結合在一起的部分:

map f []     = []
map f (x:xs) = (\v vs -> f v : vs) x (map f xs)

現在的相似之處非常清楚。 我們甚至可以寫一些名稱來使並行化更明確:

map f []     = z              where z = []
map f (x:xs) = k x (map f xs) where k = \v vs -> f v : vs

只需替換go在上面看到map f任何地方,您就會看到定義是相同的! 因此,本着DRY的精神,我們可以嘗試將foldr重復用於以上內容:

map f = foldr (\v vs -> f v : vs) []

這使您對如何從map到文件foldr 一直到給出的定義只是一些語法技巧。 現在,我們將重點介紹foldr的function參數:

\v vs -> f v : vs
= { writing the infix operator prefix instead }
\v vs -> (:) (f v) vs
= { eta reduction }
\v -> (:) (f v)
= { definition of function composition }
\v -> ((:) . f) v
= { eta reduction }
(:) . f

因此,使用這種推理鏈,我們可以得出最終形式

map f = foldr ((:) . f) []

替代答案,希望某些人可以使用。

foldr fz xs替換每:xsf ,並[]z 所以

 a : b : c : d : []

變成

 a `f` b `f` c `f` d `f` z

現在,讓我們從map'的定義中替換值。

a `(:).f` b `(:).f` c `(:).f` d `(:).f` []

(我在擴展Haskell語法)。

現在,

a `(:).f` as

是相同的

(:) (f a) as

這與

f a : as

繼續這種轉變,我們得到

f a : f b : f c : f d : []

嘿,這看起來像是將直線map f應用於[a,b,c,d] ,不是嗎?

首先你需要了解

foldr (:) []

另一個只是在缺點之前應用函數f ,因此等效於map

暫無
暫無

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

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