12

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?

3
  • If you want to make 'lists' like this, consider data NestList a = Elem a | Nest [a], then you can write Nest [ Nest [], Nest [ Nest [] ] ] to any depth. Commented Sep 23, 2018 at 11:41
  • 1
    @AJFarmar perhaps you meant data NestedList a = Elem a | Nest [NestedList a]. Commented Sep 23, 2018 at 22:32
  • 1
    @WillNess You're right, I can't change it now though! Commented Sep 24, 2018 at 6:42

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

Comments

6

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]]].

1 Comment

we could stress that this is only possible because of the use of several literal []s, but if we'd try let s=[[], [[]]] in [s, [s], [[s]]] then it couldn't ... possibly ...... wait ..... nah, it also works! :) Because s is not "a thing", but "a polymorphic definition"! What really doesn't work is (\s -> [s, [s], [[s]]]) [[], [[]]] because lambda function's parameter type is monomorphic.
3

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.

5 Comments

@Vladimir What do you mean? I just copy-and-pasted the list from your question and named the empty lists.
slist has only 3 elements, see length slist
@Vladimir I was labeling the empty lists, not the elements of slist. I've added some spaces to make this clearer.
then why do you use two letters (a and c) for empty list in one record?
@Vladimir Because the different empty lists have different types here. For example the type of a is equal to the type of [b] (but notably not the type of b). So the elements of the list all have the same type because the individual empty lists don't.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.