JoeDonald
JoeDonald

Reputation: 125

How to combine two lists in Haskell

I want to make a list of lists like this:

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

This what i have by now:

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

But this code gives me: [[1, 2, 3], [4, 5, 6]] and is not what I need.

Upvotes: 4

Views: 9150

Answers (2)

Lamdas Everywhere
Lamdas Everywhere

Reputation: 1686

There are such things as heterogeneous lists in Haskell, but they're not particularly trivial or beginner-friendly:

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

This is also a good read: https://wiki.haskell.org/Heterogenous_collections

You're probably best off trying to see if you can make your own data type that encapsulates both simple values and lists of values:

data IntOrList = AnInt Int | AList [Int]

But then you'll have to unwrap your values, which might be an added layer that you don't want to deal with. At least they'll all be able to share a list though: someList = [AnInt 5, AnInt 7, AList [1, 2, 5, 8], AnInt 2]

Upvotes: 3

Ami Tavory
Ami Tavory

Reputation: 76297

As m0nhawk writes in the comments, you can't directly have a Haskell List of both lists of integers and integers. There are several alternatives, though.


One alternative is indeed to use a list of lists of integers ([[1, 2, 3], [4], [5], [6]]), like this:

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

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

(running this indeed prints [[1, 2, 3], [4], [5], [6]]).


Another alternative is to use 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]

Upvotes: 6

Related Questions