user11323942
user11323942

Reputation:

Convert Tuple into Foldable

Is there a way to derive Foldable from Tuple? At least when the tuple is homogeneous?

For example let's say I have (1,2,3) and I want to reverse it or to transform it into [1,2,3] and similar things.

I've tried to do something like

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

but I need a sort of equivalent of fold with lens...

and actually I see that I can do

 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

Upvotes: 2

Views: 1057

Answers (2)

duplode
duplode

Reputation: 34378

In addition to Willem's answer, 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]

Upvotes: 3

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476699

but I would need instead

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

which doesn't compile

The reason why this does not compile is because (:) :: a -> [a] -> [a] expects a list as second argument, but with foldr1Of, you provide it the last element of your fold, which is here a number.

You can solve it by using foldrOf :: Getting (Endo r) s a -> (a -> r -> r) -> r -> s -> r instead:

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

Here we thus pass [] as the "initial accumulator".

We can thus convert several several "containers" to lists with:

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

For example:

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]

Upvotes: 3

Related Questions