Skip to content

Instantly share code, notes, and snippets.

@Lysxia
Created June 27, 2019 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lysxia/c7bdcbba548ee019bf6b3f1e388bd660 to your computer and use it in GitHub Desktop.
Save Lysxia/c7bdcbba548ee019bf6b3f1e388bd660 to your computer and use it in GitHub Desktop.
{-# LANGUAGE
TypeFamilies,
ConstraintKinds,
FlexibleInstances,
FlexibleContexts,
MultiParamTypeClasses,
StandaloneDeriving,
UndecidableInstances,
QuantifiedConstraints,
TypeApplications,
ScopedTypeVariables,
DerivingVia
#-}
import Data.Coerce
import Data.Kind (Type)
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import Data.Vector.Generic.Mutable.Base (MVector(..))
import Unsafe.Coerce (unsafeCoerce)
class Generic_ a where
type Rep_ (a :: Type) :: Type
to_ :: a -> Rep_ a
from_ :: Rep_ a -> a
type CMV s a = (Coercible (UM.MVector s a) (UM.MVector s (Rep_ a)), MVector UM.MVector (Rep_ a))
gbasicLength :: forall a s. CMV s a => UM.MVector s a -> Int
gbasicLength = basicLength @UM.MVector @(Rep_ a) @s . coerce
gbasicUnsafeSlice :: forall a s. CMV s a => Int -> Int -> UM.MVector s a -> UM.MVector s a
gbasicUnsafeSlice i j = uncoercemv . basicUnsafeSlice @UM.MVector @(Rep_ a) @s i j . coerce
-- etc.
uncoercemv :: CMV s a => UM.MVector s (Rep_ a) -> UM.MVector s a
uncoercemv = unsafeCoerce
data MyType = MyCons Int Bool ()
instance MVector UM.MVector MyType where
basicLength = gbasicLength
basicUnsafeSlice = gbasicUnsafeSlice
-- etc.
newtype instance UM.MVector s MyType
= MVMyType { unMVMyType :: UM.MVector s (Rep_ MyType) }
instance Generic_ MyType where
type Rep_ MyType = (Int, Bool, ())
to_ (MyCons a b c) = (a, b, c)
from_ (a, b, c) = MyCons a b c
main = return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment