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 HOp开发者_如何学编程enGL. 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?
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 Monad
s at each step. I haven't really used hxt
much, but if these are the Arrow
s 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)
精彩评论