#haskell
Вопрос:
Почему это не работает?
summ :: (Num a) => [a] -> Int
summ [] = 0;
summ (x:list) = x summ list
Это потому, что он не уверен, что x summ list
это всегда Int? Если a
Num
нет, то не было ли произведено какое-то преобразование ?
Комментарии:
1. Действительно, ваше подозрение верно: подумайте, что было бы, если бы мы побежали
summ [1.3, 2.1]
. Сигнатура типа утверждает, что это правильный вызов (поскольку двойники-этоNum
s) и что результатом являетсяInt
-но это не может быть целое число.
Ответ №1:
Вы используете ( ) :: Num a => a -> a -> a
in x summ list
. Как следует из подписи типа, и операнд, и результат имеют один и тот же тип. Если у вас , таким образом, есть x
тип Num a => a
a, то summ list
также должен быть того же типа a
, а не an Int
.
Таким образом, вам следует работать с:
summ :: Num a => [a] -> a
summ [] = 0
summ (x:list) = x summ list
с a
типом результата as. Если вы используете список Int
s в качестве параметра, то вы получите Int
результат as, а если вы используете список Integer
s в качестве параметра, то это приведет к получению Integer
.
Если вы знаете, что элементы вашего списка имеют тип, который является членом класса Integral
типов, вы можете использовать useo f fromIntegral :: (Integral a, Num b) => a -> b
для преобразования их в Int
:
summ :: Integral a => [a] -> Int
summ [] = 0
summ (x:list) = fromIntegral x summ list
но это, скорее всего , не очень хорошая идея, так как вы работаете с an Integer
, такие числа могут быть произвольно большими и, следовательно, могут привести к переполнению.