Haskell Repa - обход 2D-массива

Я пытаюсь пройти по 2D-массиву, который я создал с помощью repa, пока у меня есть функция, которая вызывается для каждого элемента, но я не понимаю, какая существует фундаментальная концепция, которая не позволяет мне выполнять выражения внутри этой функции, что у меня пока есть следующее:

 drawTile ::(DIM2 -> Int) -> DIM2 -> Int
 drawTile f (Z :. i :. j) = do
   <this is where i want to do some IO>

 drawScene :: [GLuint] -> Array U DIM2 Int -> GLFW.Window -> IO()
 drawScene texs map win = do
   x <- computeP $(traverse map id drawTile)::IO (Array UDIM2 Int)
   return ()

Вы можете не обращать внимания на текстуры и OpenGL, это будет игра. Я получаю ошибки компиляции, когда пытаюсь использовать функцию с побочными эффектами в функции drawTile. как мне выполнить какое-то выражение (например, напечатать "привет"), где я хочу? есть ли другой более простой способ применить функцию к каждому элементу в массиве repa?


person Vince Moosetaffy    schedule 28.10.2016    source источник
comment
Это противоречит точке зрения repa (хотя это не означает, что это невозможно). repa - это все о распараллеливании вычислений на массивах различной формы. IO, однако, по своей природе является последовательным. Кроме того, traverse не означает то же, что и _5 _...   -  person Alec    schedule 28.10.2016
comment
в моем фактическом коде написано Data.Array.Repa.traverse, но спасибо, это было немного головной болью. Сообщите мне, имеет ли это смысл, я хочу распараллеливание на каждом кадре рисования GL, чтобы, даже если каждый кадр является последовательным, рисование всех отдельных компонентов каждого кадра было параллельным. Спасибо за быстрый ответ   -  person Vince Moosetaffy    schedule 28.10.2016
comment
Если каждый из отдельных компонентов может быть нарисован независимо, вы можете попытаться сделать drawTile чистым, затем сложить массив, чтобы объединить чистые компоненты, и, наконец, фактически нарисовать на экране.   -  person Alec    schedule 28.10.2016
comment
Вы говорите, что я могу заранее создавать чистые функции, составлять их вместе, и они не будут выполняться, пока я не вызову их в main?   -  person Vince Moosetaffy    schedule 28.10.2016


Ответы (1)


Я сделал то, что предложил пользователь alec, и вернул список операций ввода-вывода, а затем упорядочил их все вместе, используя следующую функцию:

resequence_ :: [IO ()] -> IO ()
resequence_ = foldr (>>) (return ())

Спасибо еще раз за помощь. для справки в будущем, я ошибочно передавал IO, и проблема была не в repa.

person Vince Moosetaffy    schedule 30.10.2016