将元组转换为可折叠

时间:2019-05-05 09:44:37

标签: haskell lens foldable

是否可以从Foldable导出Tuple? 至少当元组是同质的时?

例如,假设我有(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) 

无法编译

2 个答案:

答案 0 :(得分:4)

  

但我需要代替

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

无法编译

之所以无法编译,是因为(:) :: 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]

在这里,我们因此将[]作为“初始累加器”传递。

因此,我们可以使用以下方法将几个“容器”转换为列表:

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]

答案 1 :(得分:3)

除了Willem's answer外,值得注意的是Control.Lens.Fold提供了Data.Foldable中几乎所有内容的类似物。其中包括toList,它变成toListOf

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