2015-03-20 2 views
0

Я работаю над Project Euler # 41, и это часть моего решения проблемы, которую я не могу понять, как обойти Haskell, ожидая [Int] от [Integer]. Diglist работает отлично, но я включил его на всякий случай, когда ошибка каким-то образом вовлекает его.Не удалось совместить тип `Integer 'с` Int'

digList :: Integer -> [Integer] 
digList n = digList' [] n where 
     digList' xs n 
       | n < 10  = n : xs 
       | otherwise = digList' (lsd : xs) nxt 
       where 
        lsd = n `mod` 10 
        nxt = n `div` 10 

isNPandigital :: Integer -> Bool 
isNPandigital n = isnp 1 (digList n) where --error on this line 
    isnp i xs 
     | i `elem` xs = isnp i $ delete i xs 
     | i == length (digList n) = null xs 
     | otherwise = False 

Ошибка:

Couldn't match type `Integer' with `Int' 
Expected type: [Int] 
Actual type: [Integer] 
In the return type of a call of `digList' 
In the second argument of `isnp', namely `(digList n)' 
In the expression: isnp 1 (digList n) 

ответ

2

Аргумент i к isnp выводится быть Int, потому что вы используете i `elem` xs, и потому, что вы используете i == length (digList n). Компилятор видит, что i должен быть Int, так как вы сравниваете его length (digList n), который всегда возвращает Int, и вы используете i `elem` xs, поэтому xs должен иметь тип [Int], но вы передаете в (digList n) для xs и digList n имеет тип [Integer], отсюда ошибка.

+0

Интересно. Каким будет идиоматический способ справиться с этим различием типа в Haskell? Я закончил делать '(toInteger. Length. DigList) xs', так что ghc выводил бы тип' i' как 'Integer', но дополнительный вызов toInteger кажется ... грязным для меня. – Wolf

+1

@wolf вы также можете использовать 'genericLength :: Num i => [a] -> i'. Он немного медленнее, чем просто 'length', но может возвращать любой номер. –

Смежные вопросы