I'm trying to use fromPtr from accelerate-io to scoop an image out of OpenCV and into an Accelerate array. The documentation for this feature is obtuse, and this example won't compile (I can't install accelerate-examples because of Criterion). This code:
import Foreign.Ptr
import Foreign.C.Types
import AI.CV.CxCore
import AI.CV.HighGui
import Data.Array.Accelerate as A
import Data.Array.Accelerate.IO as A
import Data.Word
main :: IO ()
main = do
capture <- cvCreateCameraCapture 0
frame <- cvQueryFrame capture
imgPtr <- cvGetImage frame -- Ptr IplImage -> Ptr Word
arr <- A.fromPtr (Z :. 480 :. 640) ((), castPtr imgPtr)
return ()
results in Couldn't match expected type 'BlockPtrs (EltRepr e0)' with actual type '((), Ptr b0)'. The type variables 'e0', 'b0' are ambiguous.
Removing the castPtr gives me Couldn't match expected type 'BlockPtrs (EltRepr e0)' with actual type '((), Ptr Word8)'. The type variable 'e0' is ambiguous.
Looking at the definitions for BlockPtrs and EltRepr only makes me more confused. But, adding a type signature to the expression, as in (((), imgPtr) :: BlockPtrs ((), Word8)) gives an expected type of BlockPtrs (EltRepr e0) and an actual type of BlockPtrs ((), Word8).
Does anyone here have experience with fromPtr?
EDIT: Getting closer. I tried to use the constructor EltRepr before, but it didn't occur to me to import its originating module. D'oh! But, now that I have done so, replacing the type signature with :: BlockPtrs (EltRepr Word8):
Couldn't match type `BlockPtrs (EltRepr e0)' with `((), Ptr Word8)'
The type variable `e0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: BlockPtrs (EltRepr e0)
Actual type: BlockPtrs (EltRepr Word8)
EDIT: Answered by Reid Barton. It compiles for me now, thanks! "Final" code:
import AI.CV.CxCore
import AI.CV.HighGui
import Data.Array.Accelerate as A
import Data.Array.Accelerate.IO as A
import Data.Array.Accelerate.Array.Sugar (EltRepr)
main :: IO ()
main = do
capture <- cvCreateCameraCapture 0
frame <- cvQueryFrame capture
imgPtr <- cvGetImage frame
(arr :: Array (Z :. Int :. Int :. Int) Word8) <- A.fromPtr
(Z :. 480 :. 640 :. 3)
(((), imgPtr) :: BlockPtrs (EltRepr Word8))
return ()
GHC needs to know which type
eyou want to usefromPtrat to provide theElt einstance.Apparently
EltRepris a type family/associated type, soEltRepr edoes not determinee. (There's no reason why there can't be two typese1ande2for whichEltRepr e1andEltRepr e2are the same type.) So GHC can never conclude from the types of the arguments tofromPtrwhich typeeto use.Arrayis an ordinary type constructor, soArray sh edoes determinee. So you should put a type ascription onarrinstead.(This will require some extension which GHC will let you know about.) Or, if you actually use
arrin a way that determines the type of its elements to beWord8, you won't need this type ascription.