
rodrigo.bonifacio wrote:
I guess this is a very simple question. How can I convert IO [XmlTree] to just a list of XmlTree?
You can't, unless you use `unsafePeformIO`, as others have already pointed out. Yet others have, more "correctly," suggested that you use do notation to bind a variable with the type you expect. I want to go into a little more detail .I have a spontaneous Monad tutorial to throw out, I guess. How you can convert a value of type `IO [XmlTree]` is probably the wrong question. The right question is how you can convert a function of type `[XmlTree] -> A` into a function of type `IO [XmlTree] -> IO A`. The correct answer has many names: fmap, liftA, liftM, (<$>) :: Monad m => (a -> b) -> (m a -> m b) I will use `fmap` to mean any of the above names. In your case, applying fmap to a function foo: foo :: [XmlTree] -> A fmap foo :: IO [XmlTree] -> IO A So any time you need to pass an IO value to a pure function, this is one way to do it. Suppose that the function actually returns an IO value, though. Here, we will call the function `bar`: bar :: [XmlTree] -> IO A fmap bar :: IO [XmlTree] -> IO (IO A) Now we seem to be in a similar situation as before. We have an extra IO that we don't want. There is a function for this: join :: Monad m => m (m a) -> m a So, we can use `join` to transform an expression of type `IO (IO a)` to an expression of type `IO a`. Putting it all together: bar :: [XmlTree] -> IO A fmap bar :: IO [XmlTree] -> IO (IO A) join . fmap bar :: IO [XmlTree] -> IO A And we now have a sensible function again. Of course, this is a common pattern, using `join` and `fmap` together, so we have yet another function: (=<<) :: Monad m => (a -> m b) -> (m a -> m b) (Note that this has a different argument order than (>>=). I prefer this form since it emphasizes that it actually transforms a function.) So, now we have bar :: [XmlTree] -> IO A (bar =<<) :: IO [XmlTree] -> IO A Putting it all together, with a function that gives us the `IO [XmlTree]`: xmlTree :: IO [XmlTree] bar :: [XmlTree] -> IO A bar =<< XmlTree :: IO A And that last line is equivalent to this in do notation: do tree <- xmlTree bar tree If you have any questions, please do ask. I understand that it can appear quite dense to a beginner. I'm thinking about using this approach in a blog article, which would have more detail and examples, but I would like to be aware of potential stumbling blocks. - Jake