Haskell 防止GHC优化共享运行时表示的值之间的转换(f.i.Int->;Integer)

Haskell 防止GHC优化共享运行时表示的值之间的转换(f.i.Int->;Integer),haskell,ghc,Haskell,Ghc,我目前正在考虑在中从所有提升的但与newtype类似的类型(带有单个参数的单个构造函数)中删除一级间接寻址的可能性;例如,Int将获得一个普通的数字作为其运行时表示(即42),而不是一个包含构造函数标记和数字的数组(即[0,42]) 然而,GHC似乎正在优化具有相同运行时表示的类型之间的转换,这打破了这种模式。考虑以下事项: data Integer = Small Int# | Big ExternalGMPStuff data Int = I# Int# convert :: Int -&

我目前正在考虑在中从所有提升的但与newtype类似的类型(带有单个参数的单个构造函数)中删除一级间接寻址的可能性;例如,
Int
将获得一个普通的
数字作为其运行时表示(即
42
),而不是一个包含构造函数标记和数字的数组(即
[0,42]

然而,GHC似乎正在优化具有相同运行时表示的类型之间的转换,这打破了这种模式。考虑以下事项:

data Integer = Small Int# | Big ExternalGMPStuff
data Int = I# Int#

convert :: Int -> Integer
convert (I# i) = Small i
这就是用GHC定义
整数
Int
类型的方式。现在,
Small
I
将具有相同的构造函数标记,这意味着对于较小的值,
Integer
Int
将具有相同的运行时表示。因此,
convert
功能可能会被合理地优化掉,实际上,在某些情况下,GHC似乎正在这样做


Int
的运行时表示形式更改为与
Int#
的运行时表示形式相同时,这种优化显然不再有效。由于能够从所有不需要间接寻址的类型中移除一个级别将是一个相当大的胜利,我非常想知道:

a) GHC在什么情况下执行这种优化(触发这种优化不是很简单,我在
base
integer gmp
中找不到明确执行这种优化的重写规则);和
b) 有没有办法让它停止而不必完全禁用优化?

它真的做到了吗?我怀疑是其他优化让它看起来像是这样的,我不太确定它是否真的是这样;我模糊地记得在
base
的某个地方看到过类似的东西(注释、重写规则、其他东西;可能是特定于整数的),但触发这种行为比实际发生的情况要复杂得多。答案很可能是“在任何情况下,永远不会”。“当Int的运行时表示形式更改为与Int#的运行时表示形式相同时”,但这会更改程序的语义
Int
已装箱,但
Int#
未装箱。我错过什么了吗?如果您不想使用
data Int=I#Int#
提供的间接寻址,那么为什么不使用
Int#
?在许多程序中,间接寻址是可取的。在“正常”Haskell中,确实如此,是的。然而,当编译到Javascript时(Haste就是这么做的),我们可以通过做一些稍微聪明的事情,以更少的开销获得间接寻址的所有语义。如果GHC现在这样做,我会感到惊讶,但也许它应该这样做!