我正在尝试使用Accelerator-io中的fromPtr将图像从OpenCV中挖出并放入Accelerate数组中。该功能的文档比较晦涩,并且this example不会编译(由于Criterion,我无法安装加速示例)。这段代码:

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 ()

结果为Couldn't match expected type 'BlockPtrs (EltRepr e0)' with actual type '((), Ptr b0)'. The type variables 'e0', 'b0' are ambiguous.
删除castPtr给我Couldn't match expected type 'BlockPtrs (EltRepr e0)' with actual type '((), Ptr Word8)'. The type variable 'e0' is ambiguous.
查看BlockPtrsEltRepr的定义只会让我更加困惑。但是,在表达式中添加类型签名(如(((), imgPtr) :: BlockPtrs ((), Word8))一样)会得到预期的BlockPtrs (EltRepr e0)类型和实际的BlockPtrs ((), Word8)类型。

这里有没有人有fromPtr的经验?

编辑:越来越近。我曾尝试使用构造函数EltRepr,但导入其原始模块并没有发生。天哪!但是,现在我已经这样做了,将类型签名替换为:: 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)

编辑:由Reid Barton回答。现在为我编译了,谢谢! “最终”代码:
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 ()

最佳答案

fromPtr :: (Shape sh, Elt e) => sh -> BlockPtrs (EltRepr e) -> IO (Array sh e)

GHC需要知道您想使用e的哪种类型的fromPtr来提供Elt e实例。

显然EltRepr是类型族/关联类型,因此EltRepr e不能确定e。 (没有理由为什么没有e1e2是相同类型的EltRepr e1EltRepr e2这两种类型。)因此,GHC永远无法从fromPtr的参数类型(使用的e类型)中得出结论。
Array是一个普通的类型构造函数,因此Array sh e确实确定e。因此,您应该在arr上放置类型说明。
  (arr :: Array (Z :. Int :. Int) Word8) <- A.fromPtr (Z :. 480 :. 640) ((), castPtr imgPtr)

(这将需要GHC让您知道的一些扩展。)或者,如果您实际使用arr来确定其元素的类型为Word8,则不需要此类型说明。

10-07 21:00