Как сложить количество двойников? - PullRequest
1 голос
/ 31 марта 2019

Как я могу сложить Double с? Я думал, что sum будет работать из коробки, и когда я просто использую вывод типа, это действительно кажется, но когда я даю сигнатуру типа, фиксирующую тип вывода на Double, сумма становится бесконечной!

Это не работает:

doubles :: Int -> Int -> Double
doubles maxk maxn =  sum [1/(fromIntegral(i*(j+1)^(2*i)))|i<-[1..maxk],j<-[1..maxn]]

Я вижу это поведение:

*Main> doubles 20 1500
Infinity

Однако, без подписи типа, тот же код:

doubles maxk maxn =  sum [1/(fromIntegral(i*(j+1)^(2*i)))|i<-[1..maxk],j<-[1..maxn]]

Дает разумный ответ:

*Main> doubles 20 1500
0.692481179869307

Что дает?

1 Ответ

5 голосов
/ 31 марта 2019

Вторая функция имеет другой тип, чем первая.

(Дробный a1, Интегральный a2) => a2 -> a2 -> a1

здесь a2любой тип, который имеет экземпляр Integral.И Int, и Integer реализуют Integral.Целое число - это произвольный тип точности: оно будет содержать любое число, независимо от его размера, вплоть до предела памяти вашей машины.Инт нет.Например:

(10 :: Integer) ^ 100 == 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

(10 :: Int) = 100 == 0

TheВторой случай может произойти в вашей первой функции.И тогда 1/0 == Бесконечность

Когда нет явного объявления типа, Haskell будет считать, что любой натуральный числовой литерал фактически является целым числом.Вот почему вторая функция работает с целыми числами, и результат лучше

...