
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

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 Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

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

Den tors 12 juli 2018 13:15Francesco Ariis
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

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.

Ah, I see. Thanks a lot for the clarification!
Patrik Iselind
Den fre 13 juli 2018 09:31Francesco 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 Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (3)
-
Francesco Ariis
-
mrx
-
PY