IO question

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

IO question

Rustom Mody
I have this from Peyton Jones awkward squad paper

getTwoChars :: IO (Char,Char)
getTwoChars = do
            c1 <- getChar
            c2 <- getChar
            return (c1,c2)

Can someone explain what is happening here?
*Main> getTwoChars
ab
('a','b')
*Main> getTwoChars
a
('\n','a')
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111027/42ef6b50/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

IO question

Ertugrul Söylemez
Rustom Mody <rustompmody at gmail.com> wrote:

> I have this from Peyton Jones awkward squad paper
>
> getTwoChars :: IO (Char,Char)
> getTwoChars = do
>             c1 <- getChar
>             c2 <- getChar
>             return (c1,c2)
>
> Can someone explain what is happening here?
> *Main> getTwoChars
> ab
> ('a','b')

This seems perfectly fine.  The getTwoChars action is one that will
result in a 2-tuple of Chars, when run.  The getChar action is a value
of type IO Char, so it's an action that, when run, yields a Char.  While
defining an IO action like getTwoChars you can use other actions to
build it.  In the context of IO each action is executed in sequence (the
two getChars) you have there, and the "<-" arrow is used to give their
results a name, if you care about them.

The "return x" action is just the action, which will yield x when run,
so "return (c1, c2)" will yield the tuple in conformance to getTwoChar's
type.


> *Main> getTwoChars
> a
> ('\n','a')

This one seems really odd.  Assuming that you typed "a" and then pressed
the Return key, I don't know why it happens for you.  For me it doesn't
happen.  I get the expected ('a', '\n').


Greets,
Ertugrul


--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/




Reply | Threaded
Open this post in threaded view
|

IO question

Thomas Davie
In reply to this post by Rustom Mody
The issue you're hitting I believe is two fold:

1) stdin has line buffering turned on.  This means that the first example does not run until return is pressed because the input is not sent to ghci until then.
2) You now have a 3rd character on stdin that's yet to be consumed ? a new line character, this causes getTwoChars to grab that, and the following character when it's run a second time.

You could solve this by turning off buffering on stdin, or by making getTwoChars ignore new lines.

Bob
if (*ra4 != 0xffc78948) { return false; }

On 27 Oct 2011, at 15:48, Rustom Mody wrote:

> I have this from Peyton Jones awkward squad paper
>
> getTwoChars :: IO (Char,Char)
> getTwoChars = do
>             c1 <- getChar
>             c2 <- getChar
>             return (c1,c2)
>
> Can someone explain what is happening here?
> *Main> getTwoChars
> ab
> ('a','b')
> *Main> getTwoChars
> a
> ('\n','a')
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111027/78168f9d/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

IO question

Daniel Fischer
In reply to this post by Rustom Mody
On Thursday 27 October 2011, 16:48:44, Rustom Mody wrote:

> I have this from Peyton Jones awkward squad paper
>
> getTwoChars :: IO (Char,Char)
> getTwoChars = do
>             c1 <- getChar
>             c2 <- getChar
>             return (c1,c2)
>
> Can someone explain what is happening here?
> *Main> getTwoChars
> ab
> ('a','b')
> *Main> getTwoChars
> a
> ('\n','a')

Hmm, here I get

Prelude> let getTwoChars :: IO (Char, Char); getTwoChars = do { x <-
getChar; y <- getChar; return (x,y); }
Prelude> getTwoChars
ab('a','b')
Prelude> getTwoChars
ac('a','c')
Prelude>

Since your result pair appears on a different line, it seems that your
input stream is line buffered and you have to press <Return> to make the
input available to getChar. Then the entered newline isn't removed by the
first getTwoChars, so it becomes the first Char gotten by the second
invocation of getTwoChars.

What's your OS and ghc version?


Reply | Threaded
Open this post in threaded view
|

IO question

Rustom Mody
Ok...

Seems to only happen inside emacs (inf-haskell mode)
At a shell it is as expected:

*Main> getTwoChars
a
('a','\n')

So I guess its an emacs (comint-mode derivative to inferior process) issue.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111027/ddaad117/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

IO question

Brandon Allbery
In reply to this post by Rustom Mody
On Thu, Oct 27, 2011 at 10:48, Rustom Mody <rustompmody at gmail.com> wrote:

> Can someone explain what is happening here?
> *Main> getTwoChars
> ab
> ('a','b')
> *Main> getTwoChars
> a
> ('\n','a')
>

The code is doing exactly what it says.  getTwoChars reads two characters
--- *not* a line.  So the next character waiting to be read is the newline,
which is returned by the next getTwoChars.

This may depend to some extent on the platform, as Unix defaults to a
line-oriented input interface (at the OS level) but Windows to
character-oriented input.

--
brandon s allbery                                      allbery.b at gmail.com
wandering unix systems administrator (available)     (412) 475-9364 vm/sms
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111027/62c64b43/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

IO question

Ertugrul Söylemez
Brandon Allbery <allbery.b at gmail.com> wrote:

> On Thu, Oct 27, 2011 at 10:48, Rustom Mody <rustompmody at gmail.com> wrote:
>
> > Can someone explain what is happening here?
> > *Main> getTwoChars
> > ab
> > ('a','b')
> > *Main> getTwoChars
> > a
> > ('\n','a')
>
> The code is doing exactly what it says.  getTwoChars reads two
> characters --- *not* a line.  So the next character waiting to be read
> is the newline, which is returned by the next getTwoChars.
>
> This may depend to some extent on the platform, as Unix defaults to a
> line-oriented input interface (at the OS level) but Windows to
> character-oriented input.

I can't confirm that.  This is true for compiled programs, but when
running

    liftA2 (,) getChar getChar

on the GHCi command line, it seems to use NoBuffering.


Greets,
Ertugrul


--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/




Reply | Threaded
Open this post in threaded view
|

IO question

Brandon Allbery
On Fri, Oct 28, 2011 at 11:01, Ertugrul Soeylemez <es at ertes.de> wrote:

> Brandon Allbery <allbery.b at gmail.com> wrote:
> > The code is doing exactly what it says.  getTwoChars reads two
> > characters --- *not* a line.  So the next character waiting to be read
> > is the newline, which is returned by the next getTwoChars.
> >
> > This may depend to some extent on the platform, as Unix defaults to a
> > line-oriented input interface (at the OS level) but Windows to
> > character-oriented input.
>
> I can't confirm that.  This is true for compiled programs, but when
> running
>
>    liftA2 (,) getChar getChar
>
> on the GHCi command line, it seems to use NoBuffering.


The dependency is a little more complex than simply the tty line buffering
mode; that simply obscures the problem a bit, it doesn't actually modify it.
 Specifically:  in character mode each read terminates without the need to
read a newline, whereas in line mode the newline is needed to pass
characters from the OS to the program; but in either mode the newline is
still read as a separate character.  So in line mode it can *appear* to be
treating each of those as a separate line, when in reality it isn't (and you
find that out when you get the '\n').

(I don't recall offhand if the GHC runtime conflates the file buffering mode
with the tty line mode on Unix.  This is not the file handle buffering mode;
it's the termios "icanon" setting.  But ghci does seem to run with icanon
cleared, at least interactively as distinct from ":main".)

--
brandon s allbery                                      allbery.b at gmail.com
wandering unix systems administrator (available)     (412) 475-9364 vm/sms
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20111028/fdd6c7a0/attachment-0001.htm>