Понимание «спринта» после оценки полиморфного выражения

Дано:

λ: let x = 1 + 2

Я запускаю sprint, чтобы напечатать его значение:

λ: :sprint x
x = _

Как и ожидалось, он не оценен.

Но после оценки x:

λ: x
3

sprint по-прежнему выводит _, т.е. без оценки:

λ: :sprint x
x = _

Это почему?


person Kevin Meredith    schedule 22.06.2016    source источник


Ответы (1)


Это потому, что x полиморфен.

Сравнить с:

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

Когда x является полиморфным, GHCI не может заменить преобразователь конкретным значением, поскольку вы можете оценить его позже как другой тип.

person ErikR    schedule 22.06.2016
comment
Почему полиморфизм влияет на его значение выражения? - person Kevin Meredith; 22.06.2016
comment
Я думаю, ключевой момент здесь в том, что «значение» с ограничением класса типа, например Num a => a, на самом деле не является простым значением. Вместо этого это фактически функция из словаря класса типов в значение. - person Alexis King; 22.06.2016
comment
@KevinMeredith Невозможно запустить функцию +, не зная, что это за функция. Например, комплексное число будет иметь два поля, оба из которых необходимо добавить; скомпилированный код для этой версии + совершенно другой. Когда вы оценивали x (набирая x в подсказке), GHCi должен был выбрать конкретный тип (по умолчанию; если бы правила по умолчанию не применялись, это вызвало бы ошибку) и вызвать версию этого типа +. Но x сам по себе является всем (Num) типами; это всегда неоцененный преобразователь, потому что вы всегда можете создать новые экземпляры Num, а затем использовать x в качестве этих типов. - person Ben; 22.06.2016
comment
@KevinMeredith Alexis Kind прав на 100%. Во время компиляции Haskell классы типов удаляются. Это делается путем введения явных аргументов словаря, которые передают информацию о том, какой экземпляр следует использовать. Таким образом, x становится функцией с типом NumDict a -> a, где тип NumDict a содержит реализации операций Num для типа a. Когда вы пытаетесь оценить x, его тип по умолчанию становится Integer, и, таким образом, вы фактически выполняете x NumDictInteger, где NumDictInteger определяется объявлением экземпляра Integer для Num. - person Bakuriu; 22.06.2016