- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个调用 Haskell 的 C 函数。 C 函数传递一个 Haskell 数据类型的 StablePtr,Haskell 代码需要更改它的一些值。执行此操作的有效方法是什么?例如,考虑以下内容
foreign export ccall editChar :: StablePtr MyObject -> CInt -> CChar -> IO ()
data MyObject = Obj String
editChar :: StablePtr MyObject -> CInt -> CChar -> IO ()
editChar cMyObjectPtr index newChar = do
-- Code goes here
为了将 index 处的 Char 设置为 newChar,如何实现 editChar 尽可能高效和 Haskelly?最终,被改变的对象在内存方面将相当大并且有许多子组件,因此作为 editChar 的结果返回一个新对象是不可能的。
最佳答案
您不能改变 MyObject
中的 Char
。实际上,您根本无法改变 StablePtr
的内容。您所能做的就是取消引用 StablePtr
以取回您的 MyObject
。
如果你定义
newtype MyObject = Obj (IORef String)
(或 MVar
而不是 IORef
)
然后您就可以通过通常的方法对其进行变异。
就其值(value)而言,如果内存消耗是您所关心的,String
根本不适合;它使用 5 machine words per character .然而,“返回一个新值”的开销可能没有你想象的那么高:感谢共享,将 Char
添加到 String
不会复制整个字符串,而是只是重用对“旧”字符串的引用。具有树结构,例如 Seq
,这些优势也适用于替换元素。
但是,如果您要进行大量修改,那么您可能需要考虑一个可变的 vector。 .
当然,如果 String
只是一个示例(如您最后一段所暗示的),那么此建议不一定适用。但是如果你有
data Huge = Huge { giganticPart :: Gigantic, smallPart :: Int }
那么 myHuge { smallPart = 42 }
不会复制整个 Gigantic
,如果 Gigantic
是一个合适的树结构,您将能够对其进行修改而无需复制整个内容。这是纯函数式持久数据结构的核心思想,也是 Haskell 最重要的优势之一。
关于Haskell + StablePtr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8964362/
我有一个调用 Haskell 的 C 函数。 C 函数传递一个 Haskell 数据类型的 StablePtr,Haskell 代码需要更改它的一些值。执行此操作的有效方法是什么?例如,考虑以下内容
我是一名优秀的程序员,十分优秀!