У меня есть следующий код:
{-# NOINLINE i2i #-}
i2i :: Int -> Integer
i2i x = toInteger x
main = print $ i2i 2
Запуск GHC с флагом -ddump-simp дает:
[Arity 1
NoCafRefs
Str: DmdType U(L)]
Main.i2i = GHC.Real.toInteger1
Кажется, что преобразование из Int в Integer является ленивым. Почему это так - есть ли случай, когда я могу иметь
(toInteger _|_ ::Int) /= _|_
Редактировать: вопрос больше связан с анализатором строгости GHC, чем с ленью как таковой. Этот код был получен из изучения стандартной средней функции:
--mean :: Integer -> Integer -> [Integer] -> Double
mean :: Integer -> Int -> [Integer] -> Double
mean acc n [] = fromIntegral acc / fromIntegral n
mean acc n (x:xs) = mean (acc + x) (n + 1) xs
main = print $ mean 0 0 [1..1000000]
Этот код выполняется в пространстве O (N). Когда я раскомментирую первую строку, потребление пространства изменится на O (1). Кажется, это сводится к вызову fromIntegral, который, в свою очередь, сводится к toInteger. Анализатор строгости почему-то не может сделать вывод о строгости преобразования, что мне кажется странным.