[英]Explain how does new foldr work in Haskell
新的Haskell程序员将尽快找到源代码,以了解如何实现文件foldr
。 好吧,代码曾经很简单(不要指望新手知道OldList
或FTP
)。
新代码如何工作?
-- | Map each element of the structure to a monoid,
-- and combine the results.
foldMap :: Monoid m => (a -> m) -> t a -> m
foldMap f = foldr (mappend . f) mempty
-- | Right-associative fold of a structure.
--
-- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z
我只提到@duplode链接中未包含的部分。
首先,您列出的那些实现是默认方法。 每个Foldable
类型都需要提供至少其中一种的自己的特定版本,而list( []
)提供foldr
, 该文件 foldr
实现方式与以往一样:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
(为了提高效率,它与Haskell报告版本有所不同。)
另外,由于duplode的回答是那个奇怪的#.
,因此Foldable
默认设置中的细微变化#.
运算符,在GHC的Data.Foldable
代码内部使用。 基本上,它是的更有效的版本.
仅当left函数是新类型的包装器/展开器函数时才有效。 它是使用新的新型强制机制定义的,并且基本上没有优化:
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
(#.) _f = coerce
{-# INLINE (#.) #-}
我对文件夹的思维模型遵循以下结构:
给定形式为a:(b:(c:[]))的列表,将所有“:”替换为给定的op(第一个参数),然后将“ []”替换为给定的初始值(第二个参数) 。
伪代码示例:
foldr (+) 0 [1,2,3,4] = 1 + 2 + 3 + 4 + 0
记住, [1,2,3,4]
等效于1:(2:(3:(4:[])))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.