packages feed

unboxing-vector-0.1.0.0: test/Foo.hs

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Foo
  (Foo -- the constructor is not exported!
  ,mkFoo
  ) where
import Data.Vector.Unboxing (Unboxable(..))
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Generic.Mutable as GM
import Control.DeepSeq (NFData)
import GHC.Generics
import Data.Coerce

newtype Foo = Foo Int deriving (Eq,Show,Generic)

instance NFData Foo

mkFoo :: Foo
mkFoo = Foo 42

-- Comparison of Data.Vector.Unboxing and Data.Vector.Unboxed:

-- The number of lines needed to enable 'Data.Vector.Unboxing.Vector Foo' is ...

instance Unboxable Foo where
  type Rep Foo = Int -- needs TypeFamilies here

-- ... only 2 lines!
-- Also, you can use GeneralizedNewtypeDeriving + UndecidableInstances if you want to write less.

-- On the other hand, the number of lines needed to enable 'Data.Vector.Unboxed.Vector Foo' is ...

newtype instance UM.MVector s Foo = MV_Foo (UM.MVector s Int)
newtype instance U.Vector Foo = V_Foo (U.Vector Int)

instance GM.MVector UM.MVector Foo where -- needs MultiParamTypeClasses here
  basicLength (MV_Foo mv) = GM.basicLength mv
  basicUnsafeSlice i l (MV_Foo mv) = MV_Foo (GM.basicUnsafeSlice i l mv)
  basicOverlaps (MV_Foo mv) (MV_Foo mv') = GM.basicOverlaps mv mv'
  basicUnsafeNew l = MV_Foo <$> GM.basicUnsafeNew l
  basicInitialize (MV_Foo mv) = GM.basicInitialize mv
  basicUnsafeReplicate i x = MV_Foo <$> GM.basicUnsafeReplicate i (coerce x)
  basicUnsafeRead (MV_Foo mv) i = coerce <$> GM.basicUnsafeRead mv i
  basicUnsafeWrite (MV_Foo mv) i x = GM.basicUnsafeWrite mv i (coerce x)
  basicClear (MV_Foo mv) = GM.basicClear mv
  basicSet (MV_Foo mv) x = GM.basicSet mv (coerce x)
  basicUnsafeCopy (MV_Foo mv) (MV_Foo mv') = GM.basicUnsafeCopy mv mv'
  basicUnsafeMove (MV_Foo mv) (MV_Foo mv') = GM.basicUnsafeMove mv mv'
  basicUnsafeGrow (MV_Foo mv) n = MV_Foo <$> GM.basicUnsafeGrow mv n

instance G.Vector U.Vector Foo where -- needs MultiParamTypeClasses here
  basicUnsafeFreeze (MV_Foo mv) = V_Foo <$> G.basicUnsafeFreeze mv
  basicUnsafeThaw (V_Foo v) = MV_Foo <$> G.basicUnsafeThaw v
  basicLength (V_Foo v) = G.basicLength v
  basicUnsafeSlice i l (V_Foo v) = V_Foo (G.basicUnsafeSlice i l v)
  basicUnsafeIndexM (V_Foo v) i = coerce <$> G.basicUnsafeIndexM v i
  basicUnsafeCopy (MV_Foo mv) (V_Foo v) = G.basicUnsafeCopy mv v
  elemseq (V_Foo v) x y = G.elemseq v (coerce x) y

instance U.Unbox Foo

-- ... enormous!
-- Unfortunately, you cannot use GeneralizedNewtypeDeriving to MVector/Vector classes.