Reputation: 3625
I'm having some trouble defining the type signature when using the generic vector interface. I want to construct a method that can work on both boxed and unboxed vectors.
This works, but is constrained to boxed vectors:
import Control.Monad.ST
import Data.Vector as V
import Data.Vector.Generic as VG
import Data.Vector.Generic.Mutable as VGM
import Data.Vector.Mutable as VM
import Data.Vector.Unboxed as VU
import Data.Vector.Unboxed.Mutable as VUM
mySwap :: V.Vector a -> V.Vector a
mySwap vec = runST $ do
vec_mut <- V.thaw vec
VM.swap vec_mut 0 1
V.unsafeFreeze vec_mut
If I change V
to VG
in order to use the generic interface, then two arguments are needed for the vector in the type signature, but I'm not sure how to constrain the first argument:
mySwap2 :: VG.Vector v a -> VG.Vector v a
mySwap2 vec = runST $ do
vec_mut <- VG.thaw vec
VGM.swap vec_mut 0 1
VG.unsafeFreeze vec_mut
Expected a type, but
VG.Vector v a
has kindghc-prim-.4.0.0:GHC.Prim.Constraint
Upvotes: 1
Views: 203
Reputation: 52057
I just removed the type signature and let GHC guide me:
gswap v = runST $ do
vmut <- VG.thaw v
VGM.swap vmut 0 1
VG.unsafeFreeze vmut
At first this yielded:
Illegal equational constraint Mutable v ~ Mutable v
(Use GADTs or TypeFamilies to permit this)
After adding LANGUAGE TypeFamilies
it compiled and :t gswap
returned:
gswap
:: (VG.Vector v a, VG.Vector v1 a, Mutable v1 ~ Mutable v) =>
v a -> v1 a
But if v
and v1
are the same type the mutable constraint is trivially satisfied and you don't need the TypeFamilies extension.
Upvotes: 2
Reputation: 31355
In the Generic
module, Vector
is a type class and needs to be used as a constraint, e.g.:
mySwap2 :: VG.Vector v a => v a -> v a
This means: v
is some kind of vector which is capable of holding a
s.
Upvotes: 1