sergv · GitHub

The doctest examples for UnboxViaPrim (https://hackage.haskell.org/package/vector-0.13.0.0/docs/Data-Vector-Unboxed.html#t:UnboxViaPrim) are not self-contained.

When using one of them as-is

#!/usr/bin/env cabal
{- cabal:
build-depends:
  , base
  , vector ^>= 0.13
-}
{-# LANGUAGE DerivingVia                #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TypeFamilies               #-}
module Main where
import qualified Data.Vector.Generic         as G
import qualified Data.Vector.Generic.Mutable as M
import qualified Data.Vector.Primitive       as P
import qualified Data.Vector.Unboxed         as U
newtype Foo = Foo Int deriving P.Prim
newtype instance U.MVector s Foo = MV_Int (P.MVector s Foo)
newtype instance U.Vector    Foo = V_Int  (P.Vector    Foo)
deriving via (U.UnboxViaPrim Foo) instance M.MVector MVector Foo
deriving via (U.UnboxViaPrim Foo) instance G.Vector  Vector  Foo
instance Unbox Foo
main :: IO ()
main = do
  putStrLn "OK"
  pure ()

I get following error with GHC 9.4

$ cabal run Test.hs
/tmp/test/Test.hs:24:54: error:
    Not in scope: type constructor or class ‘MVector’
    Suggested fix:
      Perhaps use one of these:
        ‘M.MVector’ (imported from Data.Vector.Generic.Mutable),
        ‘U.MVector’ (imported from Data.Vector.Unboxed),
        ‘P.MVector’ (imported from Data.Vector.Primitive)
   |
24 | deriving via (U.UnboxViaPrim Foo) instance M.MVector MVector Foo
   |                                                      ^^^^^^^
/tmp/test/Test.hs:25:54: error:
    Not in scope: type constructor or class ‘Vector’
    Suggested fix:
      Perhaps use one of these:
        ‘G.Vector’ (imported from Data.Vector.Generic),
        ‘U.Vector’ (imported from Data.Vector.Unboxed),
        ‘P.Vector’ (imported from Data.Vector.Primitive)
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  Vector  Foo
   |                                                      ^^^^^^
/tmp/test/Test.hs:26:10: error:
    Not in scope: type constructor or class ‘Unbox’
    Suggested fix:
      Perhaps use ‘U.Unbox’ (imported from Data.Vector.Unboxed)
   |
26 | instance Unbox Foo
   |          ^^^^^

After fixing qualified imports I try again with

#!/usr/bin/env cabal
{- cabal:
build-depends:
  , base
  , vector ^>= 0.13
-}
{-# LANGUAGE DerivingVia                #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TypeFamilies               #-}
module Main where
import qualified Data.Vector.Generic         as G
import qualified Data.Vector.Generic.Mutable as M
import qualified Data.Vector.Primitive       as P
import qualified Data.Vector.Unboxed         as U
newtype Foo = Foo Int deriving P.Prim
newtype instance U.MVector s Foo = MV_Int (P.MVector s Foo)
newtype instance U.Vector    Foo = V_Int  (P.Vector    Foo)
deriving via (U.UnboxViaPrim Foo) instance M.MVector U.MVector Foo
deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
instance U.Unbox Foo
main :: IO ()
main = do
  putStrLn "OK"
  pure ()

but now the error is actually interesting and this is what made me create this PR:

$ cabal run Test.hs
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(G.Mutable U.Vector s (U.UnboxViaPrim Foo)
            -> GHC.ST.ST s (U.Vector (U.UnboxViaPrim Foo)))
          @(G.Mutable U.Vector s Foo -> GHC.ST.ST s (U.Vector Foo))
          (G.basicUnsafeFreeze @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicUnsafeFreeze’:
          G.basicUnsafeFreeze
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(G.Mutable U.Vector s (U.UnboxViaPrim Foo)
                  -> GHC.ST.ST s (U.Vector (U.UnboxViaPrim Foo)))
                @(G.Mutable U.Vector s Foo -> GHC.ST.ST s (U.Vector Foo))
                (G.basicUnsafeFreeze @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicUnsafeFreeze’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(U.Vector (U.UnboxViaPrim Foo)
            -> GHC.ST.ST s (G.Mutable U.Vector s (U.UnboxViaPrim Foo)))
          @(U.Vector Foo -> GHC.ST.ST s (G.Mutable U.Vector s Foo))
          (G.basicUnsafeThaw @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicUnsafeThaw’:
          G.basicUnsafeThaw
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(U.Vector (U.UnboxViaPrim Foo)
                  -> GHC.ST.ST s (G.Mutable U.Vector s (U.UnboxViaPrim Foo)))
                @(U.Vector Foo -> GHC.ST.ST s (G.Mutable U.Vector s Foo))
                (G.basicUnsafeThaw @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicUnsafeThaw’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(U.Vector (U.UnboxViaPrim Foo) -> Int) @(U.Vector Foo -> Int)
          (G.basicLength @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicLength’:
          G.basicLength
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(U.Vector (U.UnboxViaPrim Foo) -> Int) @(U.Vector Foo -> Int)
                (G.basicLength @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicLength’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(Int
            -> Int
            -> U.Vector (U.UnboxViaPrim Foo)
            -> U.Vector (U.UnboxViaPrim Foo))
          @(Int -> Int -> U.Vector Foo -> U.Vector Foo)
          (G.basicUnsafeSlice @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicUnsafeSlice’:
          G.basicUnsafeSlice
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(Int
                  -> Int
                  -> U.Vector (U.UnboxViaPrim Foo)
                  -> U.Vector (U.UnboxViaPrim Foo))
                @(Int -> Int -> U.Vector Foo -> U.Vector Foo)
                (G.basicUnsafeSlice @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicUnsafeSlice’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(U.Vector (U.UnboxViaPrim Foo)
            -> Int
            -> vector-stream-0.1.0.0:Data.Stream.Monadic.Box
                 (U.UnboxViaPrim Foo))
          @(U.Vector Foo
            -> Int -> vector-stream-0.1.0.0:Data.Stream.Monadic.Box Foo)
          (G.basicUnsafeIndexM @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicUnsafeIndexM’:
          G.basicUnsafeIndexM
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(U.Vector (U.UnboxViaPrim Foo)
                  -> Int
                  -> vector-stream-0.1.0.0:Data.Stream.Monadic.Box
                       (U.UnboxViaPrim Foo))
                @(U.Vector Foo
                  -> Int -> vector-stream-0.1.0.0:Data.Stream.Monadic.Box Foo)
                (G.basicUnsafeIndexM @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicUnsafeIndexM’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(G.Mutable U.Vector s (U.UnboxViaPrim Foo)
            -> U.Vector (U.UnboxViaPrim Foo) -> GHC.ST.ST s ())
          @(G.Mutable U.Vector s Foo -> U.Vector Foo -> GHC.ST.ST s ())
          (G.basicUnsafeCopy @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.basicUnsafeCopy’:
          G.basicUnsafeCopy
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(G.Mutable U.Vector s (U.UnboxViaPrim Foo)
                  -> U.Vector (U.UnboxViaPrim Foo) -> GHC.ST.ST s ())
                @(G.Mutable U.Vector s Foo -> U.Vector Foo -> GHC.ST.ST s ())
                (G.basicUnsafeCopy @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.basicUnsafeCopy’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/test/Test.hs:25:1: error:
    • Couldn't match representation of type: P.Vector Foo
                               with that of: U.Vector (U.UnboxViaPrim Foo)
        arising from a use of ‘ghc-prim-0.9.0:GHC.Prim.coerce’
      NB: ‘U.Vector’ is defined in ‘Data.Vector.Unboxed.Base’
          ‘P.Vector’ is defined in ‘Data.Vector.Primitive’
      The data constructor ‘Data.Vector.Unboxed.Base.V_UnboxViaPrim’
        of newtype ‘U.Vector (U.UnboxViaPrim a)’ is not in scope
    • In the expression:
        ghc-prim-0.9.0:GHC.Prim.coerce
          @(U.Vector (U.UnboxViaPrim Foo) -> U.UnboxViaPrim Foo -> b -> b)
          @(U.Vector Foo -> Foo -> b -> b)
          (G.elemseq @U.Vector @(U.UnboxViaPrim Foo))
      In an equation for ‘G.elemseq’:
          G.elemseq
            = ghc-prim-0.9.0:GHC.Prim.coerce
                @(U.Vector (U.UnboxViaPrim Foo) -> U.UnboxViaPrim Foo -> b -> b)
                @(U.Vector Foo -> Foo -> b -> b)
                (G.elemseq @U.Vector @(U.UnboxViaPrim Foo))
      When typechecking the code for ‘G.elemseq’
        in a derived instance for ‘G.Vector U.Vector Foo’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘G.Vector U.Vector Foo’
   |
25 | deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

finally if I fix this too I’ll get output

#!/usr/bin/env cabal
{- cabal:
build-depends:
  , base
  , vector ^>= 0.13
-}
{-# LANGUAGE DerivingVia                #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TypeFamilies               #-}
module Main where
import qualified Data.Vector.Generic         as G
import qualified Data.Vector.Generic.Mutable as M
import qualified Data.Vector.Primitive       as P
import qualified Data.Vector.Unboxed         as U
import qualified Data.Vector.Unboxed.Base    as U
newtype Foo = Foo Int deriving P.Prim
newtype instance U.MVector s Foo = MV_Int (P.MVector s Foo)
newtype instance U.Vector    Foo = V_Int  (P.Vector    Foo)
deriving via (U.UnboxViaPrim Foo) instance M.MVector U.MVector Foo
deriving via (U.UnboxViaPrim Foo) instance G.Vector  U.Vector  Foo
instance U.Unbox Foo
main :: IO ()
main = do
  putStrLn "OK"
  pure ()
$ cabal run Test.hs
OK

I propose to amend doctest for UnboxViaPrim to make it working. I have also took liberty to sort imports and qualify imported module’s names in the same way doctest for IsoUnbox does for consistency (in a separate commit for ease of discarding it if it proves too controversial).

Read the original on github.com ↗