Converting IO [XmlTree] to [XmlTree]

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
34 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Converting IO [XmlTree] to [XmlTree]

rodrigo.bonifacio

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]

Luke Palmer-2
On Tue, Apr 14, 2009 at 8: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?

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 t

Inside this block, t is an [XmlTree], and it is passed to print. Intutively, when you see

 x <- y

inside 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]

Cristiano Paris
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+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
Reply | Threaded
Open this post in threaded view
|

Re: Converting IO [XmlTree] to [XmlTree]

Alex Queiroz-2
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]

Cristiano Paris
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]

Luke Palmer-2
In reply to this post by Cristiano Paris
On Tue, Apr 14, 2009 at 9:01 AM, Cristiano Paris <[hidden email]> 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
|

Re: Converting IO [XmlTree] to [XmlTree]

Andrew Wagner
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 $ newTrees

Notice 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) context
  • You 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 actions
Hope this clarifies

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.

 


_______________________________________________
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]

John Van Enk
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 <[hidden email]> wrote:
On Tue, Apr 14, 2009 at 4:54 PM, rodrigo.bonifacio
> 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+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



--
/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]

Bulat Ziganshin-2
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_inside
in 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]

Cristiano Paris
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]

Gwern Branwen
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_IO

Maybe 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]

Luke Palmer-2
In reply to this post by Cristiano Paris
On Tue, Apr 14, 2009 at 9:24 AM, Cristiano Paris <[hidden email]> 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]

Bulat Ziganshin-2
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]

Cristiano Paris
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]

Jules Bean
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]

Cristiano Paris
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]

Jake McArthur
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]

Achim Schneider
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]

Achim Schneider
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]

Donn Cave-4
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