Как правильно построить массив ускорения, используя 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
Вам не понадобится этот тип надписи.