Как правильно построить массив ускорения, используя fromPtr в Haskell?

Я пытаюсь использовать fromPtr из ускорения-IO, чтобы черпать изображение из OpenCV в массив ускорения. Документация по этой функции является тупой, и этот пример не будет компилироваться (я не могу установить ускоритель-примеры из-за критерия). Этот код:

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.

Глядя на определения для BlockPtrs а также EltRepr только делает меня более запутанным. Но, добавив сигнатуру типа в выражение, как в (((), 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)

РЕДАКТИРОВАТЬ: ответил Рид Бартон. Это компилируется для меня сейчас, спасибо! "Финальный" код:

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 ответ

Решение
fromPtr :: (Shape sh, Elt e) => sh -> BlockPtrs (EltRepr e) -> IO (Array sh e)

GHC должен знать, какой тип e ты хочешь использовать fromPtr на обеспечение Elt e пример.

По-видимому EltRepr тип семьи / связанный тип, так EltRepr e не определяет e, (Там нет причин, почему не может быть двух типов e1 а также e2 для которого EltRepr e1 а также EltRepr 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Вам не понадобится этот тип надписи.

Другие вопросы по тегам