2017-04-16 53 views
4

我想列出如下列表:如何在Haskell中组合两个列表

[1,2,3] [4,5,6] - > [[1,2,3], 4,5,6]

这个我现在什么:

combine :: [a] -> [a] -> [[a]] 
combine xs ys = [xs,ys] 

但这代码给我:[[1,2,3],[4,5,6],而不是我需要的。

+3

你不能让下面的列表:'[[1,2,3],4,5,6]'。只有这个:'[[1,2,3],[4],[5],[6]]'。你可以将它变成一个元组。 – m0nhawk

+1

要添加一个到m0nhawk所说的内容,你不能这样做的原因是因为在Haskell列表中是同质的。这意味着列表中的每个元素必须是相同的类型。所以你可以有一个列表清单。但是你不能有一个包含列表和数字的列表。这是一个XY问题,你认为你需要这个数据结构,但你不需要。你想要解决什么实际问题? – Keatinge

回答

6

由于m0nhawk在评论中写道,你不能直接有一个整数和整数的两份名单的哈斯克尔名单。但有几种选择。


一个选择确实是使用整数的列表([[1, 2, 3], [4], [5], [6]])的列表,像这样:

combine:: [Int] -> [Int] -> [[Int]] 
combine xs ys = [xs] ++ [[y] | y <- ys] 

main = do 
    putStrLn $ show $ combine [1, 2, 3] [4, 5, 6]    

(运行这个确实打印[[1, 2, 3], [4], [5], [6]])。


另一种方法是使用algebraic data types

Prelude> data ScalarOrList = Scalar Int | List [Int] deriving(Show) 
Prelude> [List [1, 2, 3], Scalar 4, Scalar 5, Scalar 6] 
[List [1,2,3],Scalar 4,Scalar 5,Scalar 6] 
+2

顺便说一句,如果你给''都和Num'的ScalarOrList'实例['IsList'(http://hackage.haskell.org/package/base-4.9.1.0/docs/GHC-Exts.html#t: IsList),那么你实际上可以写'[[1,2,3],4,5,6]'。不过,我不一定认为这是个好主意。 – leftaroundabout

+0

@leftaroundabout感谢您的有用信息! –

3

这样的事情在Haskell异构名单,但他们不是特别琐碎或初学者友好:

https://hackage.haskell.org/package/hvect-0.4.0.0/docs/Data-HVect.html

这也是一个很好看的:https://wiki.haskell.org/Heterogenous_collections

你可能最好是不敢轻易尝试,看看是否可以作出这样的封装值的基本值和列出自己的数据类型:

data IntOrList = AnInt Int | AList [Int]

但那么你就必须解开你的价值观,这可能是您不想处理的新增图层。至少他们会所有能够分享,虽然名单:someList = [AnInt 5, AnInt 7, AList [1, 2, 5, 8], AnInt 2]