3

I am trying to get list numbers 17 digits long, then splitting it with Integer.digits, and getting the sum of those numbers. Unfortunately I've been getting unexpected behavior (my results contain a string of letters) and not sure if this is a bug or just personal mistakes.

Below is iex console of the error, results give 'Q $':

iex(4)> numbers = [
...(4)>   [1, 4, 8, 1, 3, 6, 9, 4, 2, 5, 5, 6, 3, 1, 8, 8, 7],
...(4)>   [1,5, 9, 4, 1, 3, 2, 7],
...(4)>   [1, 5, 4, 6, 5, 7, 8]
...(4)> ]
iex(5)> Enum.map(numbers, fn x -> Enum.sum(x) end)            
'Q $'

But when I remove a number from the last list it works correctly again, and gives the results expected

iex(1)> numbers = [ 
...(1)>   [1, 4, 8, 1, 3, 6, 9, 4, 2, 5, 5, 6, 3, 1, 8, 8, 7], 
...(1)>   [1,5, 9, 4, 1, 3, 2, 7], 
...(1)>   [1, 5, 4, 6, 5, 7]
...(1)> ]
iex(2)> Enum.map(numbers, fn x -> Enum.sum(x) end)
[81, 32, 28]

Is this expected behavior? Or is there some way around this, because each of my lists will need to sum 17 individual digits.

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
TheBreakthrough
  • 320
  • 1
  • 6

1 Answers1

8

Your initial result of 'Q $' is correct and is a common source of confusion for beginners. Technically your result should be [81, 32, 36], and it is. Go ahead, try this in IEx yourself:

iex> [81, 32, 36]
# => 'Q $'

iex> 'Q $' == [81, 32, 36]
# => true

It's just that in Elixir, Charlists look very similar to strings, and are represented by a list of the codepoints of the characters in it. As to the matter of why sometimes lists are printed as charlists, and sometimes not, it's because it is so only when they consist of valid codepoints.


To print your result as actual lists instead of charlists, you can pass the appropriate options to inspect:

result = Enum.map(numbers, fn x -> Enum.sum(x) end)
# => 'Q $'

inspect(result, charlists: :as_lists)
# => [81, 32, 36]

You can also configure IEx to always print charlists as lists:

iex> IEx.configure(inspect: [charlists: :as_lists])
# => :ok

iex> 'Q $'
# => [81, 32, 36]

Further readings:

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
  • Perfect, much appreciated. Would've never figured that – TheBreakthrough Oct 15 '18 at 02:00
  • 1
    Yes, much confusion for beginners.. One trick I do is prepend a non printing character to the list. 0 works well. Something like [0 | Enum.map(numbers, fn x -> Enum.sum(x) end)]. This should print [0, 81, 32, 36] – Steve Pallen Oct 15 '18 at 20:40