GHC 在解构和重建对象时是否会创建对象的新副本?
Does GHC make a new copy of an object when deconstructing and reconstructing it?
如果我有像 data T = T Int String
这样的类型和像这样的函数:
identity :: T -> T
identity (T a b) = T a b
在模式匹配中解构之后,GHC 是否会创建一个新的T 对象,其中包含对相同Int 和String 的引用?或者它 return 它接收到的是完全相同的对象(具有相同的内存地址)吗?我知道它们在语义上是等价的,我只是好奇。
一般来说,GHC 会分配一个新值,而不是在那种情况下重用该参数。在这种特殊情况下,您可以编写类似
f :: T -> T
f t@(T x y) = t
明确重用参数。不幸的是,在你真正想要这个的情况下——
fmap :: (a -> b) -> Either e a -> Either e b
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
-- GHC 将分配一个新的 Left
值,您不能简单地重用该参数,因为结果具有不同的类型。据我所知,除了 unsafeCoerce
.
之外,没有办法告诉 GHC 在这种情况下重用该参数
您可以使用 -ddump-simpl
轻松测试它。 ADT 值的分配将显示为数据构造函数的应用。
在这种情况下,GHC 确实发现它可以重用该值,甚至不必执行模式匹配:
module I where
data T = T Int String
identity :: T -> T
identity (T a b) = T a b
-
rwbarton@morphism:/tmp$ ghc -ddump-simpl I
[1 of 1] Compiling I ( I.hs, I.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 3, types: 3, coercions: 0}
I.identity :: I.T -> I.T
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType]
I.identity = \ (ds_dHN :: I.T) -> ds_dHN
即使没有启用优化也会发生这种情况,并且它也适用于具有多个构造函数的 ADT。
如果我有像 data T = T Int String
这样的类型和像这样的函数:
identity :: T -> T
identity (T a b) = T a b
在模式匹配中解构之后,GHC 是否会创建一个新的T 对象,其中包含对相同Int 和String 的引用?或者它 return 它接收到的是完全相同的对象(具有相同的内存地址)吗?我知道它们在语义上是等价的,我只是好奇。
一般来说,GHC 会分配一个新值,而不是在那种情况下重用该参数。在这种特殊情况下,您可以编写类似
f :: T -> T
f t@(T x y) = t
明确重用参数。不幸的是,在你真正想要这个的情况下——
fmap :: (a -> b) -> Either e a -> Either e b
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
-- GHC 将分配一个新的 Left
值,您不能简单地重用该参数,因为结果具有不同的类型。据我所知,除了 unsafeCoerce
.
您可以使用 -ddump-simpl
轻松测试它。 ADT 值的分配将显示为数据构造函数的应用。
在这种情况下,GHC 确实发现它可以重用该值,甚至不必执行模式匹配:
module I where
data T = T Int String
identity :: T -> T
identity (T a b) = T a b
-
rwbarton@morphism:/tmp$ ghc -ddump-simpl I
[1 of 1] Compiling I ( I.hs, I.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 3, types: 3, coercions: 0}
I.identity :: I.T -> I.T
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType]
I.identity = \ (ds_dHN :: I.T) -> ds_dHN
即使没有启用优化也会发生这种情况,并且它也适用于具有多个构造函数的 ADT。