Names in a record changes read behavior?

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

Names in a record changes read behavior?

Mike Meyer
Ok, this all works as expected:

λ> data Point = Point Float Float deriving (Show, Read)
λ> Point 1.0 1.0
Point 1.0 1.0
λ> read "Point 1.0 1.0"
*** Exception: Prelude.read: no parse
λ> read "Point 1.0 1.0" :: Point
Point 1.0 1.0

But now we add names to the values in the Point, and things change:

λ> data Point = Point {x :: Float, y :: Float } deriving (Show, Read)
λ> Point 1.0 1.0
Point {x = 1.0, y = 1.0}
λ> read "Point 1.0 1.0"
*** Exception: Prelude.read: no parse
λ> read "Point 1.0 1.0" :: Point
*** Exception: Prelude.read: no parse
λ> read "Point {x = 1.0, y = 1.0 }" :: Point
Point {x = 1.0, y = 1.0}

OK, why won't read accept the same syntax as the REPL? I can see wanting Read and Show to be inverses of each other, though I think it's a bit misguided. But if we're going to be that strict about them being inverses, shouldn't we also insist that the READ eval print loop only accept what read will accept?


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Names in a record changes read behavior?

Brandon Allbery

On Mon, Jul 27, 2015 at 4:25 PM, Mike Meyer <[hidden email]> wrote:
OK, why won't read accept the same syntax as the REPL? I can see wanting Read and Show to be inverses of each other, though I think it's a bit misguided. But if we're going to be that strict about them being inverses, shouldn't we also insist that the READ eval print loop only accept what read will accept?

Partly because ReadS isn't a very good parser, partly because of compliance with https://www.haskell.org/onlinereport/haskell2010/haskellch11.html#x18-18600011.4; notably:
  • If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.
--
brandon s allbery kf8nh                               sine nomine associates
[hidden email]                                  [hidden email]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Names in a record changes read behavior?

Mike Meyer


On Mon, Jul 27, 2015, 15:56 Brandon Allbery <[hidden email]> wrote:


On Mon, Jul 27, 2015 at 4:25 PM, Mike Meyer <[hidden email]> wrote:


OK, why won't read accept the same syntax as the REPL? I can see wanting Read and Show to be inverses of each other, though I think it's a bit misguided. But if we're going to be that strict about them being inverses, shouldn't we also insist that the READ eval print loop only accept what read will accept?



Partly because ReadS isn't a very good parser, partly because of compliance with https://www.haskell.org/onlinereport/haskell2010/haskellch11.html#x18-18600011.4; notably:If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.



So why does the REPL read not follow those rules? And is there some way to use whatever the REPL is using as the read instance in my code?


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Names in a record changes read behavior?

Brandon Allbery
On Mon, Jul 27, 2015 at 5:01 PM, Mike Meyer <[hidden email]> wrote:

On Mon, Jul 27, 2015, 15:56 Brandon Allbery <[hidden email]> wrote:

On Mon, Jul 27, 2015 at 4:25 PM, Mike Meyer <[hidden email]> wrote:=

OK, why won't read accept the same syntax as the REPL? I can see wanting Read and Show to be inverses of each other, though I think it's a bit misguided. But if we're going to be that strict about them being inverses, shouldn't we also insist that the READ eval print loop only accept what read will accept?


Partly because ReadS isn't a very good parser, partly because of compliance with https://www.haskell.org/onlinereport/haskell2010/haskellch11.html#x18-18600011.4; notably:If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.

So why does the REPL read not follow those rules? And is there some way to use whatever the REPL is using as the read instance in my code?

The REPL is ghc itself, not a Read instance. You almost certainly do not want to have all of ghc linked into your program just to use its parser and bytecode interpreter as a read alternative --- especially since that would be an *independent* environment and cannot see any types you defined in your program unless you also compile your program into that instance of ghc, at runtime.

--
brandon s allbery kf8nh                               sine nomine associates
[hidden email]                                  [hidden email]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Names in a record changes read behavior?

Jason Dagit-3
In reply to this post by Mike Meyer


On Mon, Jul 27, 2015 at 1:25 PM, Mike Meyer <[hidden email]> wrote:
Ok, this all works as expected:

λ> data Point = Point Float Float deriving (Show, Read)
λ> Point 1.0 1.0
Point 1.0 1.0
λ> read "Point 1.0 1.0"
*** Exception: Prelude.read: no parse
λ> read "Point 1.0 1.0" :: Point
Point 1.0 1.0

But now we add names to the values in the Point, and things change:

λ> data Point = Point {x :: Float, y :: Float } deriving (Show, Read)
λ> Point 1.0 1.0
Point {x = 1.0, y = 1.0}

This works because the type of Point is Point :: Float -> Float -> Point.

You could have equally written:
> let foo = Point
> foo 1.0 1.0

The parser at the REPL is looking for arbitrary Haskell expressions, and "Point 1.0 1.0" just happens to be a function application expression.

I hope that helps,
Jason

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe