list of nested empty lists in Haskell - list

Why is it possible to make such a list in Haskell:
slist = [ [], [[]], [[],[[]]] ]
As far I understand, every element has various types here (like in mathematics: Ø, {Ø} and so on). And ghci says:
> :t []
[] :: [t]
> :t [[]]
[[]] :: [[t]]
formally, I see different notes.
In other words, the first element is a simple empty list and the second one is a list of list (!) and so on.
What is wrong? Why does Haskell consider them to be the same type?

You are right, that in a Haskell list, all elements must be of the same type. And indeed, the type in your example is:
> :t slist
slist :: [[[[a]]]]
But the empty list [] can have any type, as long as it's of the form [b], but there are many possible bs. So there are many possible concrete types. One of them is for b to be of type [[[a]]], as in your slist.

Take a look at type of the first element of such a list:
> head [ [], [[]], [[],[[]]] ]
[]
it :: [[[t]]]
It's not t, but it's [[[t]]].
Why I can possibility to make in Haskell such list
Because the is nothing wrong with the type of this expression.
What is wrong? Why does Haskell consider them to be the same type?
t in the [[[[t]]]] is not a final type, it's type variable. That's why the type of the first element of this list could be a or [b] or [[c]] or [[[t]]].

An empty list can be a list of any type. It can be a list of numbers, a list of strings, or a list of lists. I mean, why wouldn't you be allowed to have an empty list of lists or even an empty list of lists of lists?
So in your list:
--a b c d
[ [], [ [] ], [ [], [ [] ] ] ]
d is an empty list, c is an empty list of lists, b is an empty list of lists of lists and a is an empty list of lists of lists of lists.

Related

"Non-exhaustive patterns" error when summing a list of lists

All I'm trying to do is sum a list of lists. Example of what I want to do:
Input: [[1,2,3],[2,5],[6,7]]
Output: [6,7,13]
The amount of lists inside the outer list can vary, and the amount of integers in each inner list can vary. I've tried a multitude of things, and this is the last one I tried but it doesn't work:
sumSubsets [[x]] = map sum [[x]]
Also, I wanted a base case of sumSubsets [] = [[]] but that causes errors as well. Any help would be appreciated.
You could use
sumSubsets x = map sum x
or even
sumSubsets = map sum
Your previous code,
sumSubsets [[x]] = map sum [[x]]
First performs a pattern match using [[x]] which matches a list containing a single element, which is itself a list containing a single element. Therefore it would work correctly on [[3]]
>> sumSubsets [[3]]
[3]
but not on [[1,2,3]] or [[1],[2]].
I think your problem stems primarily from mixing up types and values, which can happen easily to the beginner, in particular on lists. The whole confusion probably comes from the fact that in Haskell, [] is used as a data constructor as well as a type constructor.
For example, [Int] means "a list of Ints" (a type), but [1] means "the list that contains one element, namely the number 1" (a value -- meaning, the whole list is the value). Both things together:
xs :: [Int]
xs = [1]
When you write polymorphic functions, you abstract from something like the Int. For example, if you want to get the first element of a list, you can define a function that does that for any kind of list -- may they be lists of integers or lists of characters or even lists of lists:
firstElement :: [a] -> a
firstElement (x:xs) = x
[a] means "a list with elements of type a" (a type), and the a alone means "something of type a". firstElement is a function from a list with elements of type a to something of type a. a is a type variable. Since you're not saying what a should be, the function works for all kinds of lists:
*Main> firstElement [1,2,3]
1
*Main> firstElement ['a','b']
'a'
*Main> firstElement [[1,2],[3,4]]
[1,2]
When you wrote [[x]] you were perhaps thinking of the type of the first argument of the function, which would be a list of lists of elements of some type x (x is a type variable). You can still use that, but you have to put it into the type signature of your function (the line that contains the double colon):
sumSubsets :: Num a => [[a]] -> [a]
sumSubsets xs = map sum xs
I've used a here instead of x, since it's more commonly done, but you could use x, too. Unfortunately, the whole thing gets a bit complicated with the Num a which describes additional requirements on the type a (that it belongs to the numbers, since for other things, sum is not defined). To simplify matters, you could write:
sumSubsetsInts :: [[Int]] -> [Int]
sumSubsetsInts xs = map sum xs

SML How to prepend an element to the beginning of every list in a list of lists?

I tried the following:
fun consAll (nil, n) = [n]
| consAll ((x::xs), n) = [[n::x], [consAll(xs, n)]];
But it returns this error:
"Error: operator and operand don't agree [circularity]
operator domain: 'Z list list * 'Z list list list
operand: 'Z list list * 'Z list list
in expression:
((n :: x) :: nil) :: (consAll (,) :: nil) :: nil"
Please tell me where I am going wrong, I am a beginner to SML.
The SML list construction syntax isn't completely straightforward. Since we use [...] to construct literal lists, it is tempting to think we could also use that notation to destructure lists and cons elements onto the head of lists (as we can, for instance, in Prolog). But the cons operator, ::, is just an infix value constructor which takes an item of type 'a and a list of type 'a list and returns a new list with the item consed onto the head of the list. If you then enclose the result of evaluating this construction in square brackets, you have now wrapped the resulting list in another list:
- val xs = [2,3,4];
val xs = [2,3,4] : int list
- [1::xs];
val it = [[1,2,3,4]] : int list list
There are two additional errors in your definition:
First, you are creating a two-item list when you mean to be consing a head onto the tail of a list in the body of your second guarded function definition.
Second, your base is incorrect:
fun consAll (nil, n) = [n]
This says, if the list of lists is empty, then return a singleton list containing the item to be consed onto every list. But you are defining a function which should cons n onto the head of every list which is a member of the list in the first argument. When you run out of lists in the first argument, you should just return an empty list, because there are not more lists to be consed on to. Make sense?
Here are two ways of writing the function you describe. One using simple recursion, the other using the higher-order function List.map:
fun consAll ([], _) = []
| consAll ((x::xs), n) = (n::x) :: consAll(xs, n)
fun mapCons x lists = List.map (fn ls => x :: ls) lists
[[n::x], [consAll(xs, n)]] creates a two-element list but you want to prepend to a list. Use (n :: x) :: consAll(xs, n) instead.

List operation in Haskell

I have this list of type ([(Double,Double)],[(Double,Double)]). example list = ([(1.0,1.0), (2.0,1.0), (1.0,1.0), (1.0,3.0)],[(1.0,4.0), (1.0,5.0), (1.0,1.0), (1.0,2.0), (1.0,3.0), (1.0,4.0), (1.0,5.0)])
How would I access all the data after the fourth tuple (1.0, 3.0). I have already tried the tail function but doesn't seem to work. Thanks.
Well, for one, your list isn't a list, but a tuple :)
type MyData = (MyList, MyList)
type MyList = [MyListElem]
type MyListElem = (Double, Double)
Now, accessing the 2nd list is simply snd.
snd :: (a,b) -> b
So in your case:
snd :: MyData -> MyList
Alternatively, using Lens, you can use a lens on that directly:
list ^. _2
It's not a list, but a tuple of lists. In fact, a tuple of lists of tuples.
To get the second part of a tuple, use the snd command:
snd ([(1.0,1.0), (2.0,1.0), (1.0,1.0), (1.0,3.0)],[(1.0,4.0), (1.0,5.0), (1.0,1.0), (1.0,2.0), (1.0,3.0), (1.0,4.0), (1.0,5.0)])
This yields:
[(1.0,4.0),(1.0,5.0),(1.0,1.0),(1.0,2.0),(1.0,3.0),(1.0,4.0),(1.0,5.0)]
From here on, you can continue to get the parts of the second list using tail or the !! operator.
For completeness, the first part of a tuple can be obtained using the fst command.

Syntax for list construction / concatenation

I've only been at Haskell for two days now, and was wondering what the difference between the two function definitions below are:
Prelude> let swap (x1:x2:xs) = x2:x1:xs
Prelude> swap [1..5]
[2,1,3,4,5]
Prelude> let swap' (x1:x2:xs) = [x2] ++ [x1] ++ xs
Prelude> swap' [1..5]
[2,1,3,4,5]
That is, what makes x2:x1:xs different from [x2] ++ [x1] ++ xs ?
Please and thanks.
The type signatures are a good place to start:
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]
You can find these out with :type (:) and :type (++) in ghci.
As you can see from the type signatures, both are used to produce lists.
The : operator is used to construct lists (and to take them apart again for pattern matching). To make a list [1,2,3] you just build it up with 1 : 2 : 3 : []. The first element of : is the item to add on the front of the list, and the second element is either a list (also built up with : or the empty list signified by []).
The ++ operator is list concatenation. It takes two lists and appends them together. [1,2,3] ++ [4,5,6] is legal, whereas 1 ++ [1,2,3] is not.
This has nothing to do with syntax. (:) and (++) are just different operators. (:) is a constructor who constructs a list from an element and another list. (++) makes a new list that is the concatenation of two lists. Because (++) is not a constructor you can't use it in patterns.
Now we come to Syntax: the notation
[x2]
that you use is a shorthand for
x2:[]
So what you really have done in the second example is:
(x2:[]) ++ (x1:[]) ++ xs
Therefore, when constructing a list, you can't avoid (:), it's ultimatively the only way to do it. Note that you must construct intermediate lists to be able to use (++).

how to take a specific value from a tuple list in haskell?

I have a function like this:
selectValue1 :: Int -> [(Int,Int)] -> [Int]
selectValue1 a [(x,y)]= [ y |(x,y)<-[(x,y)],x<-(x,y),x==a ]
what i want to do is to pass a tuple list to the function and take the second item in the tuple if the first item in the tuple matches with the input a.But this function give me an error:
Type error in generator
*** Term : (x,y)
*** Type : (Int,Int)
*** Does not match : [a]
why this happens??How can do the above task?? Any solutions?? Thank you all..:)
selectValue1 a xs = [ y | (x,y) <- xs, x == a ]
First you shouldn't have pattern matched in the left hand side of the definition. You're just giving a name to your argument -- looking inside it, so to speak, can all happen in the list comprehension. Second, x <- (x,y) makes no sense. The rhs of the arrow in a list comprehension is always a list. In this case, it was doing nothing, so I removed it.