Конвертировать кортеж в складной - PullRequest
2 голосов
/ 05 мая 2019

Есть ли способ получить 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 ]

4 голосов
/ 05 мая 2019

но мне нужно вместо

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]
3 голосов
/ 06 мая 2019

В дополнение к ответу Виллема стоит отметить, что Control.Lens.Fold предлагает аналоги почти для всего в Data.Foldable. Это включает toList, который становится toListOf:

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