是否可以将元组列表[(Int,Int)]
转换为对任何输入大小有效的通用方法? ..我在各种问题中看到,这一般不可能
示例:
type X = [(Int,Int)]
func :: X -> [Int]
答案 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
的实例(以及Applicative
和Monad
等其他实例。因此,元组可以按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