{-# 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.