繁体   English   中英

Haskell 要列出的元组列表?

[英]Haskell List of tuples to list?

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

例子:

type X = [(Int,Int)]


func :: X -> [Int]

您的问题不太确定应如何将元组转换为列表。 我假设您想让它们变平 - 例如, [(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]

补充编辑:


traverseTraversable一起使用

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的实例(以及其他,例如ApplicativeMonad )。 所以可以通过toList. Tuple2 toList. Tuple2 (其中toList来自Data.Foldable )和

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM