Haskell要列出的元组列表?

时间:2011-06-07 18:56:10

标签: haskell

是否可以将元组列表[(Int,Int)]转换为对任何输入大小有效的通用方法? ..我在各种问题中看到,这一般不可能

示例:

type X = [(Int,Int)]


func :: X -> [Int]

5 个答案:

答案 0 :(得分:10)

lens库可以一致地处理这种情况和类似情况。

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

另外编辑:


traverse适用于Traversable

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]

答案 1 :(得分:9)

关于如何将元组转换为列表,您的问题并不十分确定。我假设您希望将它们展平 - 例如,[(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

答案 2 :(得分:6)

您还可以使用折叠并避免显式递归:

tupleToList = foldr (\(f,s) a -> f : s : a) []

或者:

tupleToList = foldl (\a (f,s) -> a ++ [f,s]) []

(对于相同类型的元素)

答案 3 :(得分:1)

这也可以通过homogeneous tuples library(免责声明:我是其作者)来实现。它定义了元组的包装器,使它们成为Traversable的实例(以及ApplicativeMonad等其他实例。因此,元组可以按toList . Tuple2转换为列表(其中toList来自Data.Foldable)和

f :: [(a, a)] -> [a]
f = concatMap (toList . Tuple2)

您也可以将它用于其他元组,例如concatMap (toList . Tuple5)等。

答案 4 :(得分:0)

f [] = []
f [(x, y) : xs] = x : y : f xs