在解构和重构对象时,GHC是否会创建对象的新副本?

时间:2015-06-28 22:57:50

标签: haskell pattern-matching ghc

如果我有类似data T = T Int String的类型和类似的函数:

identity :: T -> T
identity (T a b) = T a b

在模式匹配中解构后,GHC是否创建了一个包含对同一个Int和String的引用的新T对象?或者它返回它收到的完全相同的对象(具有相同的内存地址)?我知道他们在语义上是等同的,我只是很好奇。

2 个答案:

答案 0 :(得分:15)

一般情况下,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在这种情况下重用参数。

答案 1 :(得分:15)

您可以使用-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。