Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling an IO Monad inside an Arrow

Perhaps I'm going about this the wrong way, but I'm using HXT to read in some vertex data that I'd like to use in an array in HOpenGL. Vertex arrays need to be a Ptr which is created by calling newArray. Unfortunately newArray returns an IO Ptr, so I'm not sure how to go about using it inside an Arrow. I think I need something with a type declaration similar to IO a -> Arrow a?

like image 486
John Avatar asked Aug 30 '11 21:08

John


1 Answers

The type IO a -> Arrow a doesn't make sense; Arrow is a type class, not a specific type, much like Monad or Num. Specifically, an instance of Arrow is a type constructor taking two parameters that describes things that can be composed like functions, matching types end-to-end. So, converting IO a to an arrow could perhaps be called a conceptual type error.

I'm not sure exactly what you're trying to do, but if you really want to be using IO operations as part of an Arrow, you need your Arrow instance to include that. The simplest form of that is to observe that functions with types like a -> m b for any Monad instance can be composed in the obvious way. The hxt package seems to provide a more complicated type:

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

This is some mixture of the IO, State, and [] monads, attached to a function as above such that you can compose them going through all three Monads at each step. I haven't really used hxt much, but if these are the Arrows you're working with, it's pretty simple to lift an arbitrary IO function to serve as one--just pass the state value s through unchanged, and turn the output of the function into a singleton list. There may already be a function to do this for you, but I didn't see one at a brief glance.

Basically, you'd want something like this:

liftArrIO :: (a -> IO b) -> IOSLA s a b
liftArrIO f = IOSLA $ \s x -> fmap (\y -> (s, [y])) (f x)
like image 135
C. A. McCann Avatar answered Sep 22 '22 09:09

C. A. McCann