Вызов монады IO внутри стрелы

Возможно, я поступаю неправильно, но я использую HXT для считывания некоторых данных вершин, которые я хотел бы использовать в массиве в HOpenGL. Массивы вершин должны быть Ptr, который создается путем вызова newArray. К сожалению, newArray возвращает IO Ptr, поэтому я не уверен, как его использовать внутри стрелки. Я думаю, что мне нужно что-то с объявлением типа, похожим на IO a -> Arrow a?

1 ответ

Решение

Тип IO a -> Arrow a не имеет смысла; Arrow это класс типа, а не определенный тип, очень похоже на Monad или же Num, В частности, экземпляр Arrow это конструктор типов, принимающий два параметра, которые описывают вещи, которые могут быть составлены как функции, сопоставляя типы сквозными. Итак, преобразование IO a Стрелка может быть названа концептуальной ошибкой типа.

Я не совсем уверен, что вы пытаетесь сделать, но если вы действительно хотите использовать IO операции как часть Arrowвам нужен ваш Arrow экземпляр, чтобы включить это. Простейшей формой этого является наблюдение, что функции с такими типами, как a -> m b для любого Monad экземпляр может быть составлен очевидным образом. hxt Пакет, кажется, предоставляет более сложный тип:

newtype IOSLA s a b = IOSLA { runIOSLA :: s -> a -> IO (s, [b]) }

Это какая-то смесь IO, State, а также [] монады, прикрепленные к функции, как указано выше, так что вы можете составить их, пройдя через все три Monadна каждом шагу. Я действительно не использовал hxt много, но если это ArrowЕсли вы работаете, то довольно просто снять произвольную IO функция, чтобы служить одним - просто передать значение состояния s без изменений и превратить выходные данные функции в одноэлементный список. Возможно, уже есть функция, чтобы сделать это для вас, но я не видел ее вкратце.

По сути, вы хотели бы что-то вроде этого:

liftArrIO :: (a -> IO b) -> IOSLA s a b
liftArrIO f = IOSLA $ \s x -> fmap (\y -> (s, [y])) (f x)
Другие вопросы по тегам