Marco
Marco

Reputation: 21

*** Exception: Prelude.read: no parse

I am new to Haskell, I wrote this small script but I am having this read: no parse Exception, anyone could help me? thanks

import System.Environment
import Data.List

data ContactInfo = Contact { name :: String
                        , surname :: String
                        , mobile :: String
                        } deriving (Read, Show)

fromDt :: [String] -> ContactInfo
fromDt ds = read $ "Contact " ++ (Data.List.concat $ Data.List.intersperse " " $ Data.List.map show ds)

main = do
  let val =  fromDt ["John","Smith","223 455 2703"]
  putStrLn ("Name: " ++ name val ++ ", " ++ surname val)

Upvotes: 1

Views: 946

Answers (2)

ErikR
ErikR

Reputation: 52029

When you define a data type using record syntax, the derived read instance requires the full record syntax - i.e. you must pass a string like

ContactInfo { name = "...", surname = "...", mobile = "..." }

to read to obtain a ContactInfo value. A string like:

ContactInfo "..." "..." "..."

will result in a no parse exception. Here is a quick demo:

data ABC = ABC { a :: Int, b :: Int, c :: Int }
  deriving (Show, Read)

test1 :: ABC                  -- throws no parse exception
test1 = read "ABC 1 2 3"

test2 :: ABC                  -- works
test2 = read "ABC { a = 1, b = 2, c = 3 }"

Upvotes: 2

chi
chi

Reputation: 116139

Using read is horrible for that task, simply use the constructor Contact.

fromDt :: [String] -> ContactInfo
fromDt [n,s,m] = Contact n s m

Note that you will still get an error if the list you pass to fromDt is not 3 cells long. I would simply avoid defining this fragile function and use the constructor Contact directly wherever you would call fromDt.

Upvotes: 5

Related Questions