不変配列を表すVectorと可変配列を表すMVector

 //演算子で使われているデータ型を見てみましょう。

 vectorパッケージの//演算子では,arrayパッケージが提供する配列ではなく,Vectorという不変配列を表すデータ型を使っています。可変配列はMVector型になります。vectorパッケージでは,VectorとMVectorという独自の配列型を提供し,arrayパッケージの配列の代わりに利用しているのです。

 vectorパッケージのData.Vectorモジュールで提供されているVector型とMVector型の定義は以下の通りです。

module Data.Vector (
  -- * Boxed vectors
  Vector, MVector,
~ 略 ~
) where

~ 略 ~

-- | Boxed vectors, supporting efficient slicing.
data Vector a = Vector {-# UNPACK #-} !Int
                       {-# UNPACK #-} !Int
                       {-# UNPACK #-} !(Array a)
        deriving ( Typeable )

-- | Mutable boxed vectors keyed on the monad they live in ('IO' or @'ST' s@).
data MVector s a = MVector {-# UNPACK #-} !Int
                           {-# UNPACK #-} !Int
                           {-# UNPACK #-} !(MutableArray s a)
        deriving ( Typeable )

type IOVector = MVector RealWorld
type STVector s = MVector s

 また,Data.Vector.GenericモジュールではVectorクラス,Data.Vector.Generic.MutableモジュールではMVectorクラスという型クラスが提供されています。

Prelude Data.Vector.Generic> :i Vector
class (Data.Vector.Generic.Mutable.MVector
         (Mutable v) a) => Vector v a where
  basicUnsafeFreeze ::
    (Control.Monad.Primitive.PrimMonad m) =>
    Mutable v (Control.Monad.Primitive.PrimState m) a -> m (v a)
  basicUnsafeThaw ::
    (Control.Monad.Primitive.PrimMonad m) =>
    v a -> m (Mutable v (Control.Monad.Primitive.PrimState m) a)
~ 略 ~
  basicUnsafeIndexM :: (Monad m) => v a -> Int -> m a
~ 略 ~
Prelude Data.Vector.Generic> :m Data.Vector.Generic.Mutable
Prelude Data.Vector.Generic.Mutable> :i MVector
class MVector v a where
  basicLength :: v s a -> Int
  basicUnsafeSlice :: Int -> Int -> v s a -> v s a
~ 略 ~
  basicUnsafeCopy ::
    (Control.Monad.Primitive.PrimMonad m) =>
    v (Control.Monad.Primitive.PrimState m) a
    -> v (Control.Monad.Primitive.PrimState m) a
    -> m ()
  basicUnsafeGrow ::
    (Control.Monad.Primitive.PrimMonad m) =>
    v (Control.Monad.Primitive.PrimState m) a
    -> Int
    -> m (v (Control.Monad.Primitive.PrimState m) a)
        -- Defined in Data.Vector.Generic.Mutable

 Vectorクラスの型変数vの制約に使われている「Mutable」は型族です。unsafeFreeze関数から呼ばれるVectorクラスのbasicUnsafeFreezeメソッドの中で,可変配列から不変配列に凍結するときに使う「不変配列に対応する可変配列」を定義するのに使われています。

-- | @Mutable v s a@ is the mutable version of the pure vector type @v a@ with
-- the state token @s@
--
type family Mutable (v :: * -> *) :: * -> * -> *

-- Data.Vector でのunsafeFreeze関数の定義
import qualified Data.Vector.Generic as G
~ 略 ~
unsafeFreeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)
{-# INLINE unsafeFreeze #-}
unsafeFreeze = G.unsafeFreezee

-- Data.Vector.Generic でのunsafeFreeze関数の定義
-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without
-- copying. The mutable vector may not be used after this operation.
unsafeFreeze
  :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> m (v a)
{-# INLINE unsafeFreeze #-}
unsafeFreeze = basicUnsafeFreeze

 不変配列であるVector型と対になる可変配列は,MVector型として定義されています。Vector型はVectorクラスのインスタンス,MVector型はMVectorクラスのインスタンスになっています。

type instance G.Mutable Vector = MVector

instance G.Vector Vector a where
  {-# INLINE unsafeFreeze #-}
  unsafeFreeze (MVector i n marr)
    = Vector i n `liftM` unsafeFreezeArray marr
~ 略 ~

instance G.MVector MVector a where
  {-# INLINE basicLength #-}
  basicLength (MVector _ n _) = n

  {-# INLINE basicUnsafeSlice #-}
  basicUnsafeSlice j m (MVector i n arr) = MVector (i+j) m arr
~ 略 ~

 このように,vectorパッケージではVectorとMVectorという名前をデータ型と型クラスに共通して使用しています。

 vectorパッケージでデータ型のほかに型クラスを用意しているのは,arrayパッケージと同様に,vectorパッケージでも非ボックス化Vectorなどの特殊な配列を提供しているからです。非ボックス化Vectorについて興味のある方は,非ボックス化Vectorを提供しているData.Vector.Unboxedモジュールを見てみるとよいでしょう。