I'm trying to implement the luhn algorithm using the following code:
luhn :: Int -> Bool
luhn x = (tail $ show (foldl (\acc x -> acc + (read x :: Int)) 0 (foldr doEncrypt [] $ zip [0..] (show x)))) == "0"
where
doEncrypt (i,y) acc = if not(even i)
then head(((uncurry (+) . (`divMod` 10) . (*2)) y)) : acc
else (head y) : acc
I now got stuck with the following error:
• Non type-variable argument in the constraint: Integral [a2]
(Use FlexibleContexts to permit this)
• When checking the inferred type
doEncrypt :: forall a1 a2.
(Integral a1, Integral [a2]) =>
(a1, [a2]) -> [a2] -> [a2]
In an equation for ‘luhn’:
luhn x
= (tail
$ show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x))))
== "0"
where
doEncrypt (i, y) acc
= if not (even i) then
head (((uncurry (+) . (`divMod` 10) . (* 2)) y)) : acc
else
(head y) : acc
I see that the error suggests that the second part of the tuple (a2
) is a "Non type-variable argument". However, Haskell seems to identify this a2
argument as an Integral
while in fact it is a Char
. How can I tell Haskell that this is a Char
and that Haskell shouldn't worry any further about this variable's type? Or is there something else I'm not understanding which causes this error?
Edit:
When I remove the (head y)
and replace it by y
I get instead the following error:
• Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: [Char]
• In the third argument of ‘foldl’, namely
‘(foldr doEncrypt [] $ zip [0 .. ] (show x))’
In the first argument of ‘show’, namely
‘(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
In the second argument of ‘($)’, namely
‘show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
(head y)
, that means thaty
should be a list, but in other parts of the function body, you usey
as a number (to perform calculations on). The result is that Haskell thinks that the list should be a number, hende the error. - Willem Van Onsemhead
in the first clause instead, as well a aread
. But that being said. This looks very "chaotic". Even if it later "produces an answer", it is hard to "convince" a peer that the algorithm works correctly. So I think it might be be better to implement a cleaner solution. - Willem Van Onsem