如何打印在Haskell列表的内存地址 [英] How to print memory address of a list in Haskell
问题描述
我正在学习如何一些编程语言分配内存以结构化数据(在这种情况下,我正在学习数组)。
I'm studying how some programming languages assign memory to structured data (in this case I'm studying arrays).
我在这里创建阵列,如图在第3节。
I'm creating the array as shown here on section 3.
import Data.Array.IO
arr <- newArray (1,10) 37 :: IO (IOArray Int Int) --Sets default to 37
和我想要做的是打印每个元素的内存地址,是这样的:
And what I'm trying to do is print each element's memory address, something like this:
Array Start: <dec addr> | <hex addr> --Shows where the array itself is
Array 1: <dec addr> | <hex addr> --Memory address of the first element
Array 2: <dec addr> | <hex addr| --Memory address of the second element
这是我的问题是,我不知道怎么弄的内存地址值哈斯克尔的元素。
The problem that I have is that I don't know how to get the memory address value for an element in Haskell.
有没有类似Python的 ID(对象)的函数
或Ruby的 object.object_id
?
Is there a function similar to Python's id(object)
or Ruby's object.object_id
?
推荐答案
您可以使用下面的代码片段,我从的 GHC堆视图
包(它也包含使用国外进口拘谨
)
You can use the following snippet which I borrowed from the ghc-heap-view
package (it also contains an alternative solution using foreign import prim
):
{-# LANGUAGE MagicHash, BangPatterns #-}
import GHC.Exts
-- A datatype that has the same layout as Word and so can be casted to it.
data Ptr' a = Ptr' a
-- Any is a type to which any type can be safely unsafeCoerced to.
aToWord# :: Any -> Word#
aToWord# a = let !mb = Ptr' a in case unsafeCoerce# mb :: Word of W# addr -> addr
unsafeAddr :: a -> Int
unsafeAddr a = I# (word2Int# (aToWord# (unsafeCoerce# a)))
这通过首先包装 A
A PTR
构造函数中,然后浇铸 PTR 一个
到字
。因为 A
字段重新psented为指针$ P $,最终的字现在包含对象的地址。通常的警告也适用:这是不安全的,GHC特有的,打破了引用透明等
This works by first wrapping a
inside a Ptr'
constructor and then casting Ptr' a
to Word
. Since the a
field is represented as a pointer, the resulting word now contains the address of the object. The usual caveats apply: this is unsafe, GHC-specific, breaks referential transparency, etc.
测试:
main :: IO ()
main = do
arr <- newListArray (1,10) [1,2..] :: IO (IOArray Int Int)
a1 <- readArray arr 1
a2 <- readArray arr 2
a1' <- readArray arr 1
putStrLn $ "a1 : " ++ (show . unsafeAddr $! a1)
putStrLn $ "a1 : " ++ (show . unsafeAddr $! a1)
putStrLn $ "a2 : " ++ (show . unsafeAddr $! a2)
putStrLn $ "a2 : " ++ (show . unsafeAddr $! a2)
putStrLn $ "a1': " ++ (show . unsafeAddr $! a1')
输出:
a1 : 16785657
a1 : 16785657
a2 : 16785709
a2 : 16785709
a1': 16785657
请注意,你应该使用 unsafeAddr
与 $!
,否则你会得到一个thunk的地址将计算结果为 A的
不是 A
对象本身:
Note that you should use unsafeAddr
with $!
, otherwise you'll be getting an address of a thunk that will evaluate to a
instead of the a
object itself:
let a = 1
b = 2
c = a + b
putStrLn $ "c: " ++ (show . unsafeAddr $ c)
putStrLn $ "c: " ++ (show . unsafeAddr $! c)
putStrLn $ "c: " ++ (show . unsafeAddr $! c)
输出:
c: 9465024
c: 9467001
c: 9467001
这篇关于如何打印在Haskell列表的内存地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!