haskellfoldhaskell-lensfoldable

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


Solution

  • 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]