The type class Read

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

The type class Read

Patrik Iselind
Hi,

I'm trying to make sense of the type class `Read`. It feels to be like a function performing casting to me, similar to what you have in C and Java.

The weird thing is that the casting doesn't have to make sense, type-wise. So `read "5" :: Int` produce the integer 5 which make sense but `read "(3,'a')" :: Int` doesn't make sense to me but ghci accepts it!

This is seeing Read as a function, as it's a type class i suspect I'm missing something. Quite possibly quite a lot...

Why is the type class called `Read`?
What am I missing above?

// Patrik Iselind

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

Re: The type class Read

Paul

read "(3,'a')"::(Int, Char)  returns expected tuple. But with ":: Int" leads to runtime exception, because it calls `readsPrec` of Int and can not parse such string. But readsPrec of (a,b) where both are readable parses it successfully.


12.07.2018 13:05, mrx wrote:
Hi,

I'm trying to make sense of the type class `Read`. It feels to be like a function performing casting to me, similar to what you have in C and Java.

The weird thing is that the casting doesn't have to make sense, type-wise. So `read "5" :: Int` produce the integer 5 which make sense but `read "(3,'a')" :: Int` doesn't make sense to me but ghci accepts it!

This is seeing Read as a function, as it's a type class i suspect I'm missing something. Quite possibly quite a lot...

Why is the type class called `Read`?
What am I missing above?

// Patrik Iselind


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


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

Re: The type class Read

Francesco Ariis
In reply to this post by Patrik Iselind
Hello Patrik,

On Thu, Jul 12, 2018 at 12:05:52PM +0200, mrx wrote:
> Why is the type class called `Read`?
> What am I missing above?

we can say any instance of `Read` has to implement

    read :: Read a => String -> a
    -- the actual instance implements a different function,
    -- but that's not relevant for our example

So, a typeclass (Read, capital `r`) gives us a function (`read`,
lower-case `r`).  The function goes from  `String` (and no other
things) to our implemented type.

As you discovered, the conversion happens at runtime, the compiler
has no way to check it beforehand, and things might explode during
execution

    λ> read "18" :: Char
    *** Exception: Prelude.read: no parse
    λ> read "diciotto" :: Int
    *** Exception: Prelude.read: no parse

It is often a good idea to use `readMay` (from Safe) to handle
failures locally without throwing an exception

    readMay :: Read a => String -> Maybe a

Does this answers your question? If you have any further doubts,
shoot again
-F

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

Re: The type class Read

Patrik Iselind
Den tors 12 juli 2018 13:15Francesco Ariis <[hidden email]> skrev:
Hello Patrik,

On Thu, Jul 12, 2018 at 12:05:52PM +0200, mrx wrote:
> Why is the type class called `Read`?
> What am I missing above?

we can say any instance of `Read` has to implement

    read :: Read a => String -> a
    -- the actual instance implements a different function,
    -- but that's not relevant for our example

So, a typeclass (Read, capital `r`) gives us a function (`read`,
lower-case `r`).  The function goes from  `String` (and no other
things) to our implemented type.

That makes sense to me based on the type, sure. So read is some form of casting then? 

Does this answers your question?

Maybe, but I still don't see what I'd use it for. Is it used to for example read the contents of a file whose file name is provided as that string? 

// Patrik

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

Re: The type class Read

Francesco Ariis
On Fri, Jul 13, 2018 at 09:06:51AM +0200, mrx wrote:
> That makes sense to me based on the type, sure. So read is some form of
> casting then?

Yep, but just from `String` and nothing else.

>
> Does this answers your question?
>
>
> Maybe, but I still don't see what I'd use it for. Is it used to for example
> read the contents of a file whose file name is provided as that string?

No, you would use `readFile` for that:

    readFile :: FilePath -> IO String
    -- Filepath is a type synonym for `String`

You would use `read` to convert simple user input (which is usually
collected as String) into, say, Integers

    getLine :: IO String
    -- this could need read

And in general, `Read` is supposed to be compatible with `Show`, so
if you used `show` for any reason (some form of cheap serialisation,
etc.), `read` should work back the type:

    λ> show [1..10]
    "[1,2,3,4,5,6,7,8,9,10]"
    λ> read it :: [Int]
    [1,2,3,4,5,6,7,8,9,10]

tl;dr: cheap type parsing. For any more specialised/complex parsing,
use a proper parsing library like Parsec.
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: The type class Read

Patrik Iselind
Ah, I see. Thanks a lot for the clarification! 

Patrik Iselind

Den fre 13 juli 2018 09:31Francesco Ariis <[hidden email]> skrev:
On Fri, Jul 13, 2018 at 09:06:51AM +0200, mrx wrote:
> That makes sense to me based on the type, sure. So read is some form of
> casting then?

Yep, but just from `String` and nothing else.

>
> Does this answers your question?
>
>
> Maybe, but I still don't see what I'd use it for. Is it used to for example
> read the contents of a file whose file name is provided as that string?

No, you would use `readFile` for that:

    readFile :: FilePath -> IO String
    -- Filepath is a type synonym for `String`

You would use `read` to convert simple user input (which is usually
collected as String) into, say, Integers

    getLine :: IO String
    -- this could need read

And in general, `Read` is supposed to be compatible with `Show`, so
if you used `show` for any reason (some form of cheap serialisation,
etc.), `read` should work back the type:

    λ> show [1..10]
    "[1,2,3,4,5,6,7,8,9,10]"
    λ> read it :: [Int]
    [1,2,3,4,5,6,7,8,9,10]

tl;dr: cheap type parsing. For any more specialised/complex parsing,
use a proper parsing library like Parsec.
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners