7

在描述Haskell的 NegativeLiterals School 时,展示了一个使用语言扩展如何改变某些代码性能的示例,然后说

其他示例实际上可能会改变行为,而不是简单地降低效率

在玩弄了一些扩展之后,我找不到任何这些行为变化的实例。我只能找到他们正在谈论的性能变化以及一些在有和没有扩展时都会出错的程序。

当启用 NegativeLiterals 扩展时,哪些程序会改变它们的行为?

4

3 回答 3

6

否定字面量的区别在于我们是否否定整数然后调用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>
于 2018-01-15T18:34:18.327 回答
2

NegativeLiterals也改变了一些表达式的解析方式。一元-被解释为具有与二元相同优先级的运算符-(即 6),但直接(不NegativeLiterals-空格)后跟数字将成为文字的一部分。这是一个如何产生影响的示例:

>>> :set -XNoNegativeLiterals
>>> -1 `mod` 2
-1
>>> :set -XNegativeLiterals
>>> -1 `mod` 2
1
>>> - 1 `mod` 2
-1

我从这个StackOverflow 问题中得到了这个。

于 2019-01-29T20:35:42.177 回答
0

考虑一个固定大小的类型,例如Int8from Data.Int8这是一个以位存储的有符号整数。它的可能值范围从 -128 到 127。因此,使用默认语法,文字-128将尝试存储128在 an 中Int8然后取反,这会导致溢出。使用NegativeLiterals,它将直接构造-128Int8,避免了这种可能的错误。


事实证明, on ghci,文字128会产生一个警告,然后-128作为溢出的结果产生,因此它会-128产生正确的值。但是,我不相信这种行为是标准化的,因为Int8它是有符号类型,所以最好不要依赖这种方式的溢出行为。

于 2018-01-15T18:39:18.900 回答