title: Luhn algorithm in Haskell
body: <p>I think I have computed <a href="https://en.wikipedia.org/wiki/Luhn_algorithm" rel="nofollow noreferrer">Luhn algorithm</a> correctly in Haskell:</p>
  
  <pre><code>f1 :: Integer -&gt; [Integer]
  f1 x = if x &lt; 10 then [x] else (f1 (div x 10))++[mod x 10]
  
  f2 :: [Integer] -&gt; [Integer]
  f2 xs = [(!!) xs (x - 1) | x &lt;- [1..(length xs)] , even x]
  
  f3 :: [Integer] -&gt; [Integer]
  f3 xs = if mod (length xs) 2 /= 0 then (f2 xs) else (f2 (0:xs))
  
  f4 :: [Integer] -&gt; [Integer]
  f4 xs = map (*2) (f3 xs)
  
  f5 :: [Integer] -&gt; [[Integer]]
  f5 xs = map f1 xs
  
  f6 :: [[Integer]] -&gt; [Integer]
  f6 [] = []
  f6 (xs : xss) = xs++(f6 xss)
  
  f7 :: [Integer] -&gt; [Integer]
  f7 xs = [(!!) xs (x - 1) | x &lt;- [1..(length xs)] , odd x]
  
  f8 :: [Integer] -&gt; [Integer]
  f8 xs = if mod (length xs) 2 /= 0 then (f7 xs) else (f7 (0:xs))
  
  f9 :: [Integer] -&gt; [Integer]
  f9 xs = (f8 xs) ++ (f4 xs)
  
  f :: Integer -&gt; Integer
  f x = sum (f6 (f5 (f9 xs)))
     where xs = f1 x
  
  luhn :: Integer -&gt; Bool
  luhn x = if mod (f x) 10 == 0 then True else False
  </code></pre>
  
  <p>For example,</p>
  
  <pre><code>luhn 49927398716 ==&gt; True
  luhn 49927398717 ==&gt; False
  </code></pre>
  
  <p>Now I have to make a new function <code>sigLuhn</code> such that, given an integer <code>n</code>, with <code>luhn n == True</code>, then <code>sigLuhn n</code> gives the digit (or digits) such that if we add the digit to the final to <code>n</code>, then the new number verifies the Luhn algorithm too; if <code>luhn n == False</code> the function gives an error. For example,</p>
  
  <pre><code>sigLuhn 49927398716 ==&gt; [8]
  </code></pre>
  
  <p>because if we call <code>n = 49927398716</code> then</p>
  
  <pre><code>luhn (10*n + 8) ==&gt; True
  </code></pre>
  
  <p>being <code>8</code> the lowest integer from <code>0</code>. My thought is the next:</p>
  
  <pre><code>g1 :: Integer -&gt; Integer
  g1 x = div 10 x + 1
  
  g2 :: Integer -&gt; Integer -&gt; Integer
  g2 x y = x*(floor (10)^(g1 y)) + y
  
  g3 :: Integer -&gt; [Bool]
  g3 x = [luhn (g2 x y) | y &lt;- [1..]]
  
  g4 :: [Bool] -&gt; Int
  g4 xs = minimum (elemIndices True xs)
  
  g :: Integer -&gt; Int
  g x = g4 (g3 x)
  
  sigLuhn :: Integer -&gt; [Int]
  sigLuhn x = if (luhn x) then [g x] else error "The conditions of Luhn's algorithm are not valid"
  </code></pre>
  
  <p>The code doesn't give error but <code>sigLuhn</code> is not correct with this code. In short, if we assume that the function <code>luhn</code> is good, can you help me to write <code>sigLuhn</code> correctly? Thank you very much.</p>