Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 记录更新在内部的行为如何?_Haskell - Fatal编程技术网

Haskell 记录更新在内部的行为如何?

Haskell 记录更新在内部的行为如何?,haskell,Haskell,当我以这种方式变异foo时,复制了什么?而不是直接改变结构的一部分 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 Data Thing=Thing{a::IORef Int,b::IORef Int,(…),z:

当我以这种方式变异foo时,复制了什么?而不是直接改变结构的一部分

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
Data Thing=Thing{a::IORef Int,b::IORef Int,(…),z::IORef Int}
实例展示东西在哪里
(…一些不安全的东西…)

mkFoo=do a在第一个示例中,复制指向未更改的
Int
组件的指针(以及构造函数标记,如果您愿意的话)。复制
Int
或指向Int的指针没有多大区别,但如果组件是大型结构,则会有很大区别

由于字段不严格,因此行为与优化无关。如果字段是严格的,经过优化,它们可能会被解包到构造函数中,然后原始的
Int
值会被复制


在第二个示例中,没有复制任何内容,IORef的内容被覆盖。

要扩展Daniel的答案,您可以考虑

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
差不多

data Foo = Foo {a::Int, b::Int}
update foo x = foo{a=x}

更新字段可能会导致复制整个结构。但是,如果编译器能够证明该结构是以单线程方式使用的,那么它就可以进行适当的更新。我不知道有哪种实现可以做到这一点,但您可以想象使用单位引用计数来实现它

某物,某物,某物,
unsafePerformIO
。某物,某物,某物,完整。我认为Clean这样做是因为它的类型系统内置了单线程。Clean不是Haskell实现。是的,Clean具有唯一性类型,允许他们使用破坏性更新,例如数组。
data Foo = Foo Int Int
update (Foo a b) x = Foo x b