Ответ 1
Мне удалось получить тип DLL
, работающий с Structs
следующим образом:
{-# 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
Вот пример его использования:
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