Haskell 如何创建未绑定可变数组实例

Haskell 如何创建未绑定可变数组实例,haskell,stuarray,marray,Haskell,Stuarray,Marray,假设我有以下类型: 数据MyType=Constructor0 | Constructor1 | Constructor2 派生(等式、显示、枚举) 有没有办法创建这样的实例之一: 马瑞(Stus)MyType(ST s) 马里亚伊乌拉米伊奥酒店 目前,我将所有内容存储为Word8,并使用(包装的)fromEnum/toEnum进行转换,但感觉不太对劲。我需要严格和取消装箱,因为我在内存中使用了一个大的数据结构(>1.2Go),我不能懒洋洋地加载它。如果我没有找到任何解决方案,我将重新实

假设我有以下类型:

数据MyType=Constructor0 | Constructor1 | Constructor2
派生(等式、显示、枚举)

有没有办法创建这样的实例之一:

马瑞(Stus)MyType(ST s)
马里亚伊乌拉米伊奥酒店

目前,我将所有内容存储为Word8,并使用(包装的)fromEnum/toEnum进行转换,但感觉不太对劲。我需要严格和取消装箱,因为我在内存中使用了一个大的数据结构(>1.2Go),我不能懒洋洋地加载它。如果我没有找到任何解决方案,我将重新实现C++中的所有内容,我更倾向于避免当前的项目。
我问了关于哈斯克尔的问题,但没有得到回应,也许现在不是提问的好时机。

可以为
MArray IOUarray MyType IO
举个例子。查看
MArray IOUarray Bool IO
实例声明的源代码

由于Bool是
Enum
Bounded
的实例(其他不多),它们在创建实例时可能会使用这些类中的函数

您可能必须派生
Bounded
,但这可能不是问题,因为未绑定数组只能包含固定大小的元素

编辑:

在这篇文章中,我们可以读到

您甚至可以自己为其他简单类型(包括枚举)实现非固定数组


我能想到的最简单的实现是:只需将
STUArray
/
IOUArray
操作包装为
fromnum
/
toEnum

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

module UnpackedEnumArray (STUEArray, IOUEArray) where

import Control.Monad.ST
import Data.Array.Base
import Data.Array.IO
import Data.Array.ST

data STUEArray s i e = STUEArray { fromSTUEArray :: STUArray s i Int }
instance (Enum e) => MArray (STUEArray s) e (ST s) where
    getBounds = getBounds . fromSTUEArray
    getNumElements = getNumElements . fromSTUEArray
    newArray is = fmap STUEArray . newArray is . fromEnum
    newArray_ = fmap STUEArray . newArray_
    unsafeRead (STUEArray a) = fmap toEnum . unsafeRead a
    unsafeWrite (STUEArray a) i = unsafeWrite a i . fromEnum

data IOUEArray i e = IOUEArray { fromIOUEArray :: IOUArray i Int }
instance (Enum e) => MArray IOUEArray e IO where
    getBounds = getBounds . fromIOUEArray
    getNumElements = getNumElements . fromIOUEArray
    newArray is = fmap IOUEArray . newArray is . fromEnum
    newArray_ = fmap IOUEArray . newArray_
    unsafeRead (IOUEArray a) = fmap toEnum . unsafeRead a
    unsafeWrite (IOUEArray a) i = unsafeWrite a i . fromEnum
现在你可以

import UnpackedEnumArray
main = do
    a <- newArray (0,9) Constructor0 :: IO (IOUEArray Int MyType)
    getAssocs a >>= print
import unpacedenumarray
main=do
印刷品

同样地,
IArray
实例也可以编写得很简单。

谢谢,我没有想到要为此创建一个新类型,这是一个很好的方法。
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

module UnpackedEnumArray (STUEArray, IOUEArray) where

import Control.Monad.ST
import Data.Array.Base
import Data.Array.IO
import Data.Array.ST

data STUEArray s i e = STUEArray { fromSTUEArray :: STUArray s i Int }
instance (Enum e) => MArray (STUEArray s) e (ST s) where
    getBounds = getBounds . fromSTUEArray
    getNumElements = getNumElements . fromSTUEArray
    newArray is = fmap STUEArray . newArray is . fromEnum
    newArray_ = fmap STUEArray . newArray_
    unsafeRead (STUEArray a) = fmap toEnum . unsafeRead a
    unsafeWrite (STUEArray a) i = unsafeWrite a i . fromEnum

data IOUEArray i e = IOUEArray { fromIOUEArray :: IOUArray i Int }
instance (Enum e) => MArray IOUEArray e IO where
    getBounds = getBounds . fromIOUEArray
    getNumElements = getNumElements . fromIOUEArray
    newArray is = fmap IOUEArray . newArray is . fromEnum
    newArray_ = fmap IOUEArray . newArray_
    unsafeRead (IOUEArray a) = fmap toEnum . unsafeRead a
    unsafeWrite (IOUEArray a) i = unsafeWrite a i . fromEnum
import UnpackedEnumArray
main = do
    a <- newArray (0,9) Constructor0 :: IO (IOUEArray Int MyType)
    getAssocs a >>= print