如何打印在Haskell列表的内存地址 [英] How to print memory address of a list in Haskell

查看:148
本文介绍了如何打印在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆