data Thing = Thing {a :: Int, b :: Int, c :: Int, (...) , z :: Int} deriving Show
foo = Thing 1 2 3 4 5 (...) 26
mkBar x = x { c = 30 }
main = do print $ mkBar foo
Run Code Online (Sandbox Code Playgroud)
当我以这种方式改变foo时复制了什么?而不是直接改变结构的一部分.
Data Thing = Thing {a :: IORef Int, b :: IORef Int, (...) , z :: IORef Int}
instance Show Thing where
(...something something unsafePerformIO...)
mkFoo = do a <- newIORef 1
(...)
z <- newIORef 26
return Thing a b (...) z
mkBar x = writeIORef (c x) 30
main = do foo <- mkFoo
mkBar foo
print foo
Run Code Online (Sandbox Code Playgroud)
使用优化进行编译是否会改变此行为?
在第一个示例中,将Int复制指向未更改组件的指针(以及构造函数标记,如果您希望这样说).是否Int复制了一个或一个指针是没有太大区别的,但是如果组件是大型结构,它会.
由于字段不严格,因此行为与优化无关.如果字段是严格的,并且具有优化,则可以将它们解压缩到构造函数中,然后Int#复制原始值.
在第二个示例中,没有任何内容被复制,其内容IORef被覆盖.
为了扩展丹尼尔的答案,你可以想到
data Foo = Foo {a::Int, b::Int}
update foo x = foo{a=x}
Run Code Online (Sandbox Code Playgroud)
就像差不多一样
data Foo = Foo Int Int
update (Foo a b) x = Foo x b
Run Code Online (Sandbox Code Playgroud)