# Converting IO [XmlTree] to [XmlTree]

 Classic List Threaded
34 messages
12
Reply | Threaded
Open this post in threaded view
|

## Converting IO [XmlTree] to [XmlTree]

 Dear Sirs, I guess this is a very simple question. How can I convert IO [XmlTree] to just a list of XmlTree? Regards, Rodrigo.   _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 On Tue, Apr 14, 2009 at 8:54 AM, rodrigo.bonifacio wrote: Dear Sirs, I guess this is a very simple question. How can I convert IO [XmlTree] to just a list of XmlTree?This is very important: you cannot.But you can still get your hands on one inside a do block.  As in, if you have tree :: IO [XmlTree], then you can say, eg. printTree = do    t <- tree    print tInside this block, t is an [XmlTree], and it is passed to print. Intutively, when you see  x <- yinside a do block, if y :: IO a, for some type a, then x :: a.But there is no function that will get you from IO [XmlTree] -> [XmlTree], you have to use binding like this. Luke _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by rodrigo.bonifacio On Tue, Apr 14, 2009 at 4:54 PM, rodrigo.bonifacio <[hidden email]> wrote: > Dear Sirs, > > I guess this is a very simple question. How can I convert IO [XmlTree] to > just a list of XmlTree? Quick and dirty answer: unsafePerformIO. That's an easy finding on Hoogle: http://www.haskell.org/hoogle/?hoogle=IO+a+-%3E+aAnyhow, as the name suggest, the function is "unsafe", so you better know what you're doing. Bye, Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by rodrigo.bonifacio Hallo, On 4/14/09, rodrigo.bonifacio <[hidden email]> wrote: > > > Dear Sirs, > > I guess this is a very simple question. How can I convert IO [XmlTree] to > just a list of XmlTree? >      The short answer is: You cannot. The longer answer is: Only put things in the IO monad when you need to interact with the "outside", i. e., reading, displaying etc. Cheers, -- -alex http://www.ventonegro.org/_______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by Luke Palmer-2 On Tue, Apr 14, 2009 at 5:01 PM, Luke Palmer <[hidden email]> wrote: > ... > This is very important: you cannot. I'd answer "You shouldn't, unless you know what you are doing". In some cases, not only is unsafePerformIO desirable but also necessary (I'm thinking of Debug.Trace). Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by Cristiano Paris On Tue, Apr 14, 2009 at 9:01 AM, Cristiano Paris wrote: On Tue, Apr 14, 2009 at 4:54 PM, rodrigo.bonifacio <[hidden email]> wrote: > Dear Sirs, > > I guess this is a very simple question. How can I convert IO [XmlTree] to > just a list of XmlTree? Quick and dirty answer: unsafePerformIO.Please don't say that.  He's a beginner.You realize that the path of least resistance will be to use it, right? You see why that's not a good thing?Even experts don't use this function.(To the O.P.:  don't use it)Luke   That's an easy finding on Hoogle: http://www.haskell.org/hoogle/?hoogle=IO+a+-%3E+a Anyhow, as the name suggest, the function is "unsafe", so you better know what you're doing. Bye, Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

 In reply to this post by rodrigo.bonifacio Here's another way of looking at what others have already said. The only way you can do that is within the scope of another IO action. For example:outputXmlTrees :: IO ()outputXmlTrees = do   trees <- inputXmlTrees;  let newTrees = transform trees;  print . show $newTreesNotice a few things: First, the line "trees <- inputXmlTrees" effectively takes an IO [XmlTree] and turns it into a [XmlTrees]. That is, it runs the IO action inputXmlTrees, and gives you the resulting list of XmlTrees to work with. You can then pass these off to a pure function which will monkey around with them in a pure (non-IO) contextYou must do this in an IO action, however, and any monadic action gets its type from the last line. Thus, the last line must be of type IO something. In this case, it is simply the action that would print out the trees. Thus, this gives you a way to glue together different IO actions and pure actions and combine them into larger IO actionsHope this clarifiesOn Tue, Apr 14, 2009 at 10:54 AM, rodrigo.bonifacio wrote: Dear Sirs, I guess this is a very simple question. How can I convert IO [XmlTree] to just a list of XmlTree? Regards, Rodrigo. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Cristiano Paris > Quick and dirty answer: unsafePerformIO. You can do a lot of cool things with a table saw if you take the blade guard off. On Tue, Apr 14, 2009 at 11:01 AM, Cristiano Paris wrote: On Tue, Apr 14, 2009 at 4:54 PM, rodrigo.bonifacio <[hidden email]> wrote: > Dear Sirs,>> I guess this is a very simple question. How can I convert IO [XmlTree] to> just a list of XmlTree?Quick and dirty answer: unsafePerformIO.That's an easy finding on Hoogle: http://www.haskell.org/hoogle/?hoogle=IO+a+-%3E+aAnyhow, as the name suggest, the function is "unsafe", so you better know what you're doing.Bye,Cristiano _______________________________________________Haskell-Cafe mailing list[hidden email]http://www.haskell.org/mailman/listinfo/haskell-cafe -- /jve _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by rodrigo.bonifacio Hello rodrigo.bonifacio, Tuesday, April 14, 2009, 6:54:07 PM, you wrote: > I guess this is a very simple question. How can I convert IO > [XmlTree] to just a list of XmlTree? IO [XmlTree] is an action returning [XmlTree]. so to "convert" it to [XmlTree] you just need to execute it in IO monad: value <- action i suggest you to read http://haskell.org/haskellwiki/IO_insidein order to manage IO monad -- Best regards, Bulat mailto:[hidden email] _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Luke Palmer-2 On Tue, Apr 14, 2009 at 5:09 PM, Luke Palmer <[hidden email]> wrote: > ... > Please don't say that. He's a beginner. > You realize that the path of least resistance will be to use it, right? > You see why that's not a good thing? > Even experts don't use this function. > (To the O.P.: don't use it) Mmmh, sorry Luke but I don't understand this ostracism. unsafePerformIO is not "evil" by itself, it's there for a purpose and, as for anything else in the language, it's better to understand when to use it and when not rather than just knowing that is something that MUST not be used, without any further explanation. More, from my personal experience, knowing unsafePerformIO helped me understand better what Monads are and how they should be used. I wounder what so-called "experts" have to say about this. Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by rodrigo.bonifacio On Tue, Apr 14, 2009 at 10:54 AM, rodrigo.bonifacio <[hidden email]> wrote: > Dear Sirs, > > I guess this is a very simple question. How can I convert IO [XmlTree] to > just a list of XmlTree? > > Regards, > > Rodrigo. One good link on this topic is http://haskell.org/haskellwiki/Avoiding_IOMaybe there's no need for it be be IO [XmlTree], if you can write functions that instead produce/consume just [XmlTree]. They can always be turned later with liftM and whatnot into a IO [XmlTree] (but not the reverse). Doing as much as possible in pure code, and wrapping around it/calling it from a few short IO functions is the Haskell Way. Sometimes it looks hard to see, but XMonad is probably the best example here of how it can both be done where it looks infeasible ('What's a window manager but a bunch of IO?") and is rewarding (testability, etc. as exemplified by http://cgi.cse.unsw.edu.au/~dons/blog/2007/05/17) The best writeup on this seems to be http://www.cse.unsw.edu.au/~dons/talks/xmonad-hw07.pdf-- gwern _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Cristiano Paris On Tue, Apr 14, 2009 at 9:24 AM, Cristiano Paris wrote: On Tue, Apr 14, 2009 at 5:09 PM, Luke Palmer <[hidden email]> wrote: > ... > Please don't say that. He's a beginner. > You realize that the path of least resistance will be to use it, right? > You see why that's not a good thing? > Even experts don't use this function. > (To the O.P.: don't use it) Mmmh, sorry Luke but I don't understand this ostracism. unsafePerformIO is not "evil" by itself, it's there for a purpose and, as for anything else in the language, it's better to understand when to use it and when not rather than just knowing that is something that MUST not be used, without any further explanation.You have a point. I would like to avoid introducing unfounded authoritarian stigmas whenever possible.However, the way I see it is that unsafePerformIO *is* evil by itself, and it is only by the addition of Holy Water that it is benign to use. Ryan Ingram described it as a way to achieve "RTS extensions", which I think is a fine way to put it I consider Debug.Trace to be an instance of this: we are extending the RTS to provide execution traces. I guess it's a teaching style thing. Mostly, if someone sees "I have an IO [XmlTree] and I need an [XmlTree]", I want the "I'm asking the wrong question" synapse path to fire, rather than the "just use unsafePerformIO" one. Luke More, from my personal experience, knowing unsafePerformIO helped me understand better what Monads are and how they should be used. I wounder what so-called "experts" have to say about this. Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re[2]: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Cristiano Paris Hello Cristiano, Tuesday, April 14, 2009, 7:24:40 PM, you wrote: > unsafePerformIO is not "evil" by itself, it's there for a purpose and, > as for anything else in the language, it's better to understand when > to use it we just think that author of original question don't yet have good knowledge of IO monad baiscs and it's what he actually want to know. if the question was how to perform IO action in pure code, unsafePerformIO may be a good answer -- Best regards, Bulat mailto:[hidden email] _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Luke Palmer-2 On Tue, Apr 14, 2009 at 5:42 PM, Luke Palmer <[hidden email]> wrote: > > ... > However, the way I see it is that unsafePerformIO *is* evil by itself, and > it is only by the addition of Holy Water that it is benign to use. That's what I meant but your words are indeed more effective :) > Ryan Ingram described it as a way to achieve "RTS extensions", which I think > is a fine way to put it I consider Debug.Trace to be an instance of this: > we are extending the RTS to provide execution traces. > I guess it's a teaching style thing. Mostly, if someone sees "I have an IO > [XmlTree] and I need an [XmlTree]", I want the "I'm asking the wrong > question" synapse path to fire, rather than the "just use unsafePerformIO" > one. Yes, I think your analysis is correct. Perhaps I was a bit too dry in my original answer. Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by Cristiano Paris Cristiano Paris wrote: > On Tue, Apr 14, 2009 at 5:09 PM, Luke Palmer <[hidden email]> wrote: >> ... >> Please don't say that. He's a beginner. >> You realize that the path of least resistance will be to use it, right? >> You see why that's not a good thing? >> Even experts don't use this function. >> (To the O.P.: don't use it) > > Mmmh, sorry Luke but I don't understand this ostracism. > > unsafePerformIO is not "evil" by itself, it's there for a purpose and, > as for anything else in the language, it's better to understand when > to use it and when not rather than just knowing that is something that > MUST not be used, without any further explanation. Sure, the explanation is there if people are interested in it. However, in context, your answer was wrong. It is like someone asking: "How do I get hold of a new phone" and the answer "Pull a gun on someone walking down the street and demand they give you their phone" ...that is, the answer was solving the wrong problem, or solving it in the wrong context. If you have IO [XmlTree], then you don't have an [XmlTree] at all - rather you have a description of an (IO-involving) action which you need to run to get one. You can run it many times, or once, or never. It will (in general) give different results depending exactly when you run it. Therefore you need to carefully decide when to run it - i.e. attach it indirectly or directly into your main action, as the various other answers have shown. unsafePerformIO is not part of the haskell language - it does not respect the type system. It is an extension mechanism which allows us to add hooks into the RTS; effectively a way to extend the language. This is a useful and powerful thing, but nothing in the questioner's question suggested that language extension was what they wanted. Jules _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  On Tue, Apr 14, 2009 at 5:54 PM, Jules Bean <[hidden email]> wrote: > ... I'm convinced about what you say and perhaps I answered the way I did just because I'm convinced that, for a newbie, knowing about the existence of unsafePerformIO can't cause any harm. I was a bit surprised by the strong reaction about my citation of unsafePerformIO. Maybe it'd useful, for the future, to write a document explaining how to help newbies properly, maybe putting it in the mailing list charter. Cristiano _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe Reply | Threaded Open this post in threaded view | ## Re: Converting IO [XmlTree] to [XmlTree]  In reply to this post by rodrigo.bonifacio 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 _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by rodrigo.bonifacio "rodrigo.bonifacio" <[hidden email]> wrote: > Dear Sirs, > > I guess this is a very simple question. How can I convert IO > [XmlTree] to just a list of XmlTree? > unsafeCoerce. Seriously, you just don't, you weld stuff together using >>=. It takes an 'IO a' and a function 'a -> IO b' and returns you an 'IO b', thus preventing you from launching nuclear missiles while you're standing in front of the exhaust jets. You don't want to be able to. do-notation is a convenient short-hand: foo >>= (\bar -> return $baz bar) do bar <- foo return$ baz bar >>= doesn't only work with IO, but with any monad, that's why it's type, (>>=) :: Monad m => m a -> (a -> m b) -> m b might look intimidating, but actually isn't. For more info, have a look at Real World Haskell[1], and, after that, the Typeclassopedia[2]. As a final notice, don't listen to the others: Those are just desperate people, vainly trying to convince themselves they'd understand monads. If you see monads being compared to space suits, nuclear waste processing plants, or burritos, run far, run fast, but run. If you see them compared to applicative functors, get curious. [1]http://book.realworldhaskell.org/read/[2]http://byorgey.wordpress.com/2009/02/16/the-typeclassopedia-request-for-feedback/-- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by Cristiano Paris Cristiano Paris <[hidden email]> wrote: > I was a bit surprised by the strong reaction about my citation of > unsafePerformIO. Maybe it'd useful, for the future, to write a > document explaining how to help newbies properly, maybe putting it in > the mailing list charter. > 1) Tell them about interact. 2) If they're not satisfied, or already spoiled by the functions they    want to use, explain bind wrt. IO, then do-notation. You don't want    them to get puzzled by missing returns, or think that it's a keyword. 3) Let them catch up on monads by themselves, there's no need to    confuse people with explanations of things they already understand. In other words: 1) Explain Pointed 2) Explain Functor 3) Explain Applicative 4) Explain Monad -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

## Re: Converting IO [XmlTree] to [XmlTree]

 In reply to this post by Cristiano Paris Quoth Cristiano Paris <[hidden email]>, > I was a bit surprised by the strong reaction about my citation of > unsafePerformIO. Well, there might be a couple of things going on here.  Part of it is how to guess the unstated context of a question - I'm fairly sure that given a more thorough presentation of the question, there would have been no controversy about the answer.  The general problem is that people who are comfortable with extremely esoteric parts of Haskell and used to discussing such things here, fail to recognize when they're dealing with people who are at a point where their needs are much more basic.  (And who knows, which one was the present case?  Not really enough information to know absolutely for sure.) But as you have found, unsafePerformIO is not just an esoteric topic, it's an uncomfortable one.  We read that it isn't even part of the language, one should never really have any use for it in computation, only as a sort of meta-programming RTS thing.  Yet, you might never guess this from reading the GHC documentation, which only urges you to be careful.  Or from encountering it in fairly widespread use as a way to implement top level program state with IORefs.  This sort of unresolved tension between practice and theory rightly makes people uneasy, and in my opinion you shouldn't take it personally.  It's a good thing to occasionally probe those sore spots, and maybe if it bothers us enough it will lead to improvements.         Donn _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
12