将元组转换为可折叠

Convert Tuple into Foldable

有没有办法从 Tuple 导出 Foldable? 至少当元组是同质的?

例如,假设我有 (1,2,3),我想 reverse 或将其转换为 [1,2,3] 和类似的东西。

我试过

over each (\x -> 4 -x) (1,2,3) -- lol

但我需要一种相当于带镜头的折叠...

实际上我知道我可以做到

 foldr1Of each (\a x -> a+x) (1,2,3)

但我需要

 foldr1Of each (\a x -> a:x) (1,2,3) 

不编译

but I would need instead

foldr1Of each (\a x -> a:x) (1,2,3) 

which doesn't compile

无法编译的原因是因为 (:) :: a -> [a] -> [a] 需要一个列表作为第二个参数,但是对于 foldr1Of,您为它提供了 last 元素你的弃牌数,这里是一个数字。

你可以用foldrOf :: Getting (Endo r) s a -> (a -> r -> r) -> r -> s -> r代替:

Prelude Control.Lens> foldrOf each (:) [] (1,2,3)
[1,2,3]

这里我们将 [] 作为 "initial accumulator".

因此,我们可以将几个 "containers" 转换为列表:

toList :: Each s s a a => s -> [a]
toList = foldrOf each (:) []

例如:

Prelude Control.Lens> toList (1,2)
[1,2]
Prelude Control.Lens> toList (1,2,3)
[1,2,3]
Prelude Control.Lens> toList (1,2,3,4)
[1,2,3,4]
Prelude Control.Lens> toList [1,2,3]
[1,2,3]
Prelude Control.Lens> toList Nothing
[]
Prelude Control.Lens> toList (Just 2)
[2]

除了, it is worth noting that Control.Lens.Fold offers analogues for pretty much everything in Data.Foldable. That includes toList, which becomes toListOf

GHCi> toListOf each (1,2,3)
[1,2,3]