Haskell список кортежей в список?
можно ли преобразовать список кортежей [(Int,Int)]
как общий способ, который действителен для любого размера ввода ? .. я видел в различных вопросах, что это невозможно вообще
пример :
type X = [(Int,Int)]
func :: X -> [Int]
5 ответов
ваш вопрос не очень уверен в том, как кортежи должны быть преобразованы в список. Я предполагаю, что вы хотите их сгладить - например,[(1,2),(3,4)]
должны стать [1,2,3,4]
.
этот перевод возможен только, если эти два элемента вашего кортежа одного типа, чем вы можете сделать что-то вроде этого:
tupleToList :: [(a,a)] -> [a]
tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList _ = []
В общем случае, такой перевод невозможен. Одна вещь, которую я мог себе представить, чтобы сделать невозможное возможным использовать Either
в оберните два разных типа:
tupleToList :: [(a,b)] -> [Either a b]
tupleToList ((a,b):xs) = Left a : Right b : tupleToList xs
на объектив библиотека обрабатывает этот и подобные случаи последовательно.
> import Control.Lens
> toListOf (traverse . both) [(1,2),(3,4)]
^ ^
| |> Traversal of the tuple (a, a)
|> Traversal of a list [b]
[1,2,3,4]
для преобразования из списка списков:
> toListOf (traverse . traverse) [[1,2],[3,4],[5,6,7]]
[1,2,3,4,5,6,7]
добавление edit:
traverse
работает с проходимым
traverse
будет работать с любым типом данных, который имеет Traversable
например, деревья.
> import Data.Tree
> let t = Node 1 [Node 2 [Node 3 [], Node 4 []], Node 5 []]
> let prettyTree = drawTree . fmap show
> prettyTree t
1
|
+- 2
| |
| +- 3
| |
| `- 4
|
`- 5
> toListOf (traverse . traverse) [t, t]
[1,2,3,4,5,1,2,3,4,5]
вы также можете использовать складке и избежать явной рекурсии:
tupleToList = foldr (\(f,s) a -> f : s : a) []
или:
tupleToList = foldl (\a (f,s) -> a ++ [f,s]) []
(для элементов одного типа)
это также может быть достигнуто с помощью библиотека однородных кортежей (отказ от ответственности: который я автор). Он определяет обертки для кортежей, которые делают их экземплярами Traversable
(и других, таких как Applicative
и Monad
). Таким образом, Кортеж можно преобразовать в список с помощью toList . Tuple2
(где в список С Data.Foldable
) и
f :: [(a, a)] -> [a]
f = concatMap (toList . Tuple2)
вы также можете использовать его для других кортежей, например concatMap (toList . Tuple5)
etc.