Оценка выражений в Haskell: Исправление типа подвыражения приводит к тому, что родительское выражение оценивается в разной степени.
Я не могу объяснить следующее поведение:
Prelude> let x = 1 + 2
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = _
Теперь, когда я указываю тип для х:
Prelude> let x = 1 + 2 ::Int
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = (_,_)
Почему спецификация типа x вынуждает y к его нормальной форме со слабой головой (WHNF)?
Я случайно обнаружил это поведение при чтении параллельного и параллельного программирования Саймона Марлоу в Хаскеле.
1 ответ
Вот обоснованное предположение. В вашем первом примере
x :: Num a => a
Так
y :: Num a => (a, a)
В ядре GHC это y
это функция, которая принимает Num
словарь и дает пару. Если бы вы должны были оценить y
то GHCi установит для вас значение по умолчанию и применит Integer
толковый словарь. Но из того, что вы показали, похоже, что этого не произойдет с sprint
, Таким образом, у вас еще нет пары; у вас есть функция, которая производит один.
Когда вы специализируетесь на Int
, словарь применяется к x
так что вы получите
x :: Int
y :: (Int, Int)
Вместо функции из словаря, x
сейчас гром. Теперь не нужно применять словарь для оценки y
! y
это просто применение конструктора пары к двум указателям на x
санк. Применение конструктора не считается вычислением, поэтому оно никогда не будет отложено.