繁体   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