О возвращаемых именах в функциях

#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 , такие числа могут быть произвольно большими и, следовательно, могут привести к переполнению.