Правила десугаризации арифметических операций над Num - PullRequest
0 голосов
/ 03 июня 2018

Константы полиморфны в Хаскеле.Поэтому, когда я пишу:

foo = 5

Это приводит к:

foo = fromInteger 5

Но что, если добавить арифметические выражения?

foo = 42 - 15

В чем именно это будет происходить?

foo = fromInteger (42 - 15)

или

for = fromInteger 42 - fromInteger 15

Кроме того, какой самый простой и надежный способ наблюдать это?

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Haskell имеет полиморфные литералы.(по умолчанию только числа, но GHC имеет языковые расширения для полиморфных строковых литералов и литералов полиморфного списка)

Принудительные выражения (например, fromInteger) работают только с самим литералом, но не с выражением, поэтому

foo = 42 - 15

и

foo = fromInteger 42 - fromInteger 15

эквивалентны.

Мы можем показать, что это так, определив экземпляр Num, где поведение отличается (например, где + и - поменялись местами)

newtype Inverted a = Inverted {unInvert :: a}
  deriving (Eq, Ord, Show)

instance (Num a) => Num (Inverted a) where
  (Inverted x) + (Inverted y) = Inverted (x-y)
  (Inverted x) - (Inverted y) = Inverted (x+y)
  signum = Inverted . signum . unInvert
  (Inverted x) * (Inverted y) = Inverted (x*y)
  abs = Inverted . abs . unInvert
  fromInteger = Inverted . fromInteger

base :: Inverted Double
base = 42 - 15

fromBeforeOp :: Inverted Double
fromBeforeOp = fromInteger 42 - fromInteger 15

fromAfterOp :: Inverted Double
fromAfterOp = fromInteger (42 - 15)

Оба base и fromBeforeOp дают одинаковый (правильный по отношению к определению Inverted) ответ 57, тогда как fromAfterOp т 27.

0 голосов
/ 03 июня 2018

Обесцвечивается до

foo = fromInteger 42 - fromInteger 15

Вы можете наблюдать это, пытаясь

f :: Double -> Int -> String
f _ _ = "hello"

foo = 42 `f` 15

, где мы использовали пользовательский f вместо -.Здесь два литерала должны быть преобразованы в числовые типы перед вызовом f.Преобразование результата f было бы бессмысленным, так как это не числовой тип.

Использование - не меняет общего правила.

...