Pointers 带结构库的快速非强制指针(静态、取消装箱等)

Pointers 带结构库的快速非强制指针(静态、取消装箱等),pointers,haskell,ghc,imperative-programming,Pointers,Haskell,Ghc,Imperative Programming,我对在Haskell中实现命令式语言的项目中使用更高效的指针感兴趣。已经有了一个新的解决方案。它上面有一个字母,上面有一个字母 问题是只有一个非常复杂的例子。对于像我这样每天都不使用Haskell的人来说,与文档很少的代码、模板Haskell等作斗争是相当累人的 我需要一个简单的示例来开始,大致表达这两种数据类型中的任何一种: import Data.IORef data DLL a = DLL a (Maybe (IORef (DLL a))) (Maybe (IORef (DLL a)))

我对在Haskell中实现命令式语言的项目中使用更高效的指针感兴趣。已经有了一个新的解决方案。它上面有一个字母,上面有一个字母

问题是只有一个非常复杂的例子。对于像我这样每天都不使用Haskell的人来说,与文档很少的代码、模板Haskell等作斗争是相当累人的

我需要一个简单的示例来开始,大致表达这两种数据类型中的任何一种:

import Data.IORef

data DLL a = DLL a (Maybe (IORef (DLL a))) (Maybe (IORef (DLL a)))

data DLLINT = DLLINT Int (Maybe (IORef DLLINT)) (Maybe (IORef DLLINT))
对于精通Haskell/GHC的人来说,这应该只是几句简单的话


如何使用Struct库表达上述数据类型之一?

我设法使您的
DLL
类型使用
Struct
如下所示:

{-# LANGUAGE TemplateHaskell, RoleAnnotations #-}
module DubLiList where

import Control.Monad.Primitive
import Data.Struct.TH
import Data.Struct
import Data.Struct.Internal


makeStruct [d|
  data DLL a s = DLL
    { prev :: !(DLL a s)
    , value :: a
    , next :: !(DLL a s)
    }
  |]

new :: (PrimMonad m) => a -> m (DLL a (PrimState m))
new x = st $ newDLL Nil x Nil

insert :: (PrimMonad m) => a -> DLL a (PrimState m) -> m (DLL a (PrimState m))
insert x this = st $ do
    prev' <- get prev this
    new <- newDLL prev' x this
    set prev this new
    set next prev' new
    return new

delete :: (PrimMonad m) => DLL a (PrimState m) -> m ()
delete this = st $ do
    prev' <- get prev this
    next' <- get next this
    set next prev' next'
    set prev next' prev'

toList :: (PrimMonad m) => DLL a (PrimState m) -> m [a]
toList this = st $ do
    if isNil this then return [] else do
        x <- getField value this
        that <- get next this
        (x:) <$> toList that
{-#语言模板haskell,RoleAnnotations}
模块DubLiList在哪里
导入控制.Monad.Primitive
导入Data.Struct.TH
导入数据.Struct
导入Data.Struct.Internal
makeStruct[d|
数据DLL a s=DLL
{prev::!(DLL a s)
,value::a
,下一个::!(DLL a s)
}
|]
新::(PrimMonad m)=>a->m(DLL a(PrimMonad m))
新x=st$newDLL Nil x Nil
插入::(PrimMonad m)=>a->DLL a(PrimState m)->m(DLL a(PrimState m))
插入x this=st$do
上一页()
删除此项=st$do

prev’与问题完全正交,但是:您显然已经在向项目中添加一种不熟悉的技术(Haskell)。你确定要在项目启动之前通过添加另一个来终止它吗?我强烈建议你从简单开始。在你试图跳出深渊之前,确保那些无聊的“慢”的参考资料实际上是一个问题。(我希望这个警告不会阻止人们尝试写一个好的答案。)@DanielWagner这是一个研究项目,没有提到这一点。Haskell并不陌生,我只是在博士阶段更熟悉依赖类型编程。此外,代码是可选的,因此可能会有一种“非常快速”的编译方法使用此库,但编译代码还有两种其他方法。与其他编程语言(如Java或脚本语言)相比,基准测试非常有趣。这篇博客文章使该库听起来像是ekmett探索其复杂思想的研讨会,而不是供他人使用的一套完善的工具。据我所知,他已将其标记为“稳定性:实验性”,并另外建议您,LinkCut的实施并非用于公共用途,而是将其标记为内部。现在,我知道你不想使用它,但坦率地说,即使理解它也可能相当先进。我个人会离开这个图书馆。是的,我知道它是内部的。我仍然对运行基准测试感兴趣,因为在Haskell中使用指针可以实现较低的障碍。出于好奇,您的用例到底是什么?您是否正在用Haskell为您的命令式语言编写解释器?或者您是在试图提高语言的编译时间?(如果是这样,您是否绝对确定指针跳数是编译器中的瓶颈?)我发起了一项赏金来兑现您的回答(将尽快给您)
main :: IO ()
main = do
    dll <- new "foo"           -- [foo]
    dll' <- insert "bar" dll   -- [bar, foo]
    insert "baz" dll           -- [bar, baz, foo]

    xs <- toList dll'
    print xs