在描述Haskell的 NegativeLiterals School 时,展示了一个使用语言扩展如何改变某些代码性能的示例,然后说
其他示例实际上可能会改变行为,而不是简单地降低效率
在玩弄了一些扩展之后,我找不到任何这些行为变化的实例。我只能找到他们正在谈论的性能变化以及一些在有和没有扩展时都会出错的程序。
当启用 NegativeLiterals 扩展时,哪些程序会改变它们的行为?
在描述Haskell的 NegativeLiterals School 时,展示了一个使用语言扩展如何改变某些代码性能的示例,然后说
其他示例实际上可能会改变行为,而不是简单地降低效率
在玩弄了一些扩展之后,我找不到任何这些行为变化的实例。我只能找到他们正在谈论的性能变化以及一些在有和没有扩展时都会出错的程序。
当启用 NegativeLiterals 扩展时,哪些程序会改变它们的行为?
否定字面量的区别在于我们是否否定整数然后调用fromInteger
或调用fromInteger
然后否定codomain的类型。也就是说,fromInteger . negate
不一样negate . fromInteger
。我希望当您处于某种类型的边界时会发生这种情况-一种可能会饱和,而另一种可能会包裹。
例如,我有一个非常糟糕的类型:
data Bad = Bad Integer
deriving (Show)
instance Num Bad where
negate (Bad a) = Bad (a + 1)
fromInteger = Bad
结果:
*Main> (-1) :: Bad
Bad 2
*Main> :set -XNegativeLiterals
*Main> (-1) :: Bad
Bad (-1)
*Main>
NegativeLiterals
也改变了一些表达式的解析方式。一元-
被解释为具有与二元相同优先级的运算符-
(即 6),但直接(不NegativeLiterals
带-
空格)后跟数字将成为文字的一部分。这是一个如何产生影响的示例:
>>> :set -XNoNegativeLiterals
>>> -1 `mod` 2
-1
>>> :set -XNegativeLiterals
>>> -1 `mod` 2
1
>>> - 1 `mod` 2
-1
我从这个StackOverflow 问题中得到了这个。
考虑一个固定大小的类型,例如Int8
from Data.Int
。8
这是一个以位存储的有符号整数。它的可能值范围从 -128 到 127。因此,使用默认语法,文字-128
将尝试存储128
在 an 中Int8
然后取反,这会导致溢出。使用NegativeLiterals
,它将直接构造-128
为Int8
,避免了这种可能的错误。
事实证明, on ghci
,文字128
会产生一个警告,然后-128
作为溢出的结果产生,因此它会-128
产生正确的值。但是,我不相信这种行为是标准化的,因为Int8
它是有符号类型,所以最好不要依赖这种方式的溢出行为。