Смущает преобразование WHNF в NF в Haskell

В простом примере преобразование WHNF в NF с помощью печати работает нормально

Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3

Но в случае, тип не объявлен, он не работает.

Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _

Не могли бы вы объяснить, почему конвертация не работает в последнем случае?

1 ответ

Решение

Поскольку в GHCi ограничение мономорфизма отключено, последнее x это полиморфное значение типа x :: Num a => a, Так что это не просто целое число, а своего рода функция DictNum a -> a который готов создать значение в любом числовом типе.

В самом деле, x :: Int, x :: Float, x :: Double будет работать и производить разные значения. Эти значения численно одинаковы, но вычислительно различны, так как они являются представлениями в разных типах.

поскольку x по сути, это "множественные значения, сгенерированные по требованию", здесь нет ни одного WHNF или NF.

Обратите внимание, что если мы вычисляем (x :: Int) + (x :: Int), затем x пересчитывается дважды: GHC в общем случае не будет "кэшировать" WHNF по типу Int для последовательных вычислений. Это похоже на f 3 + f 3, где f 3 не кэшируется (запоминается).

Это двойное вычисление - именно то, чего пытается избежать ограничение мономорфизма.

Другие вопросы по тегам