如何在Haskell中使用fromPtr正确构造Accelerate数组?

时间:2014-02-24 02:12:38

标签: opencv haskell type-families type-signature accelerate-haskell

我正在尝试使用来自accele-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,但是我没有想要导入它的原始模块。 D'哦!但是,现在我已经这样做了,用:: 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 ()

1 个答案:

答案 0 :(得分:2)

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两种类型的fromPtre类型。)因此,GHC永远不能从类型中得出结论要Array使用Array sh e的{​​{1}}参数。

e是普通类型的构造函数,因此arr确定 (arr :: Array (Z :. Int :. Int) Word8) <- A.fromPtr (Z :. 480 :. 640) ((), castPtr imgPtr) 。因此,您应该在arr上添加类型归属。

Word8

(这需要一些GHC会让你知道的扩展。)或者,如果你确实使用{{1}}来确定其元素的类型为{{1}},那么你就赢了“需要这种类型的归属。