2

Version: 1.2.2, error:

List.flatten ([a,[b]]) is expected to return ([a,b]). However, this does not work properly for some cases. For example, List.flatten ([11, [[12], 13]]) returns '\v\f\r', when ([11,12,13]) is expected. Even List.flatten([10]) returns '\n'.

Why is this happening and what is the workaround, if any?

greggreg
  • 11,945
  • 6
  • 37
  • 52
  • 4
    Possible duplicate of [Elixir lists interpreted as char lists](http://stackoverflow.com/questions/30037914/elixir-lists-interpreted-as-char-lists) – Dogbert Jul 19 '16 at 14:12

3 Answers3

4

If your list consists of integers that could all represent printable UTF-8 codepoints in the ASCII set it will be output to the terminal as a charlist.

iex> [104,101,108,108,111]
'hello'

But it is very much still a list:

iex> 'hello' ++ ' there'
'hello there'

If it contains any non-printable code points, it will be output as a standard list:

iex> 'hello' ++ [0]
[104, 101, 108, 108, 111, 0]

You can see what codepoint a character has by using the ? operator:

iex> ?h
104

We can get info about the term using the i helper in iex:

iex> i 'hello'
Term
  'hello'
Data type
  List
Description
  This is a list of integers that is printed as a sequence of characters
  delimited by single quotes because all the integers in it represent valid
  ASCII characters. Conventionally, such lists of integers are referred to
  as "charlists" (more precisely, a charlist is a list of Unicode codepoints,
  and ASCII is a subset of Unicode).
Raw representation
  [104, 101, 108, 108, 111]
Reference modules
  List

Why does elixer do this? Erlang.

greggreg
  • 11,945
  • 6
  • 37
  • 52
2

Actually it's not related with List.flatten, which works fine. It's just a matter of printing printable characters as a ASCII characters. Elixir, in the contrary to many programming languages, treats charlists as a list of integers.

For instance:

a = 'abc'
hd a # 97

Consider last example from this turorial.

Also remember that string interpretation is one thing, but you still have list of integers.

hd [12, 13, 14] # 12
PatNowak
  • 5,721
  • 1
  • 25
  • 31
0

As greggreg explained, the reason why your final list - [11,12,13] - looks like '\v\f\r' instead, is because it contains all the printable acsii codepoints. Hence output is a charlist.

If you need to get the numbers from this list, instead of characters, here is what you can do:

iex> sample_list = [11,12,13] 
iex> [first | rest] = sample_list
iex> [second | rest] = rest
iex> [third | rest] = rest
iex> first
iex> 11
iex> second
iex> 12
iex> third
iex> 13

So basically, when you are taking out a number from a list, it is being converted to integer. Now since it is not a list, it cannot be converted to charlist.

Kshitij Mittal
  • 2,698
  • 3
  • 25
  • 40