Reputation: 21
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
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
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