10

次のタイプがあるとしましょう:

data MyType = Constructor0 | Constructor1 | Constructor2
            deriving (Eq,Show,Enum)

そのようなインスタンスのいずれかを作成する方法はありますか:

MArray (STUArray s) MyType (ST s)
MArray IOUarray MyType IO

とりあえずWord8で全部保存して(ラップして)fromEnum/toEnumで変換してるけどなんか違和感。メモリ内で大規模なデータ構造 (>1.2Go) を使用していて、遅延ロードできないため、厳格さとボックス化解除が必要です。解決策が見つからない場合は、すべてを C++ で再実装しますが、現在のプロジェクトでは避けたいと考えています。

#haskell で質問しましたが、回答がありませんでした。質問するのに適切な時間ではなかったのかもしれません。

4

2 に答える 2

6

私が考えることができる最も単純な実装: STUArray/IOUArray操作をfromEnum/でラップするだけ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

同様に、IArrayインスタンスも簡単に書くことができます。

于 2009-06-10T21:02:18.090 に答える
1

のインスタンスを作成MArray IOUarray MyType IOできるはずです。のインスタンス宣言のソースを見てくださいMArray IOUarray Bool IO

Bool はEnumandの両方のインスタンスであるためBounded(他にはほとんどありません)、インスタンスを作成するときにこれらのクラスの関数を使用する可能性があります。

派生する必要Boundedがあるかもしれませんが、ボックス化されていない配列には固定サイズの要素のみを含めることができるため、おそらく問題にはなりません。

編集:

この記事では、人は読むことができます

列挙型を含む他の単純な型に対して、ボックス化されていない配列を自分で実装することもできます。

于 2009-06-10T17:58:18.023 に答える