2011-11-13 9 views
5

sample input/outputottenendo l'errore Prelude.read: nessun parse

Sono molto nuovo in Haskell, ho scritto il codice per dettagli elemento e la ricerca dettaglio per ogni voce.

type Code = Int 
type Name = String 
type Database = (Code,Name) 

textfile::IO() 
textfile = appendFile "base.txt" (show[(110,"B")]) 

codice per la ricerca

fun::IO() 
fun=do putStrLn"Please enter the code of the product" 
     x<-getLine 
     let y = read x :: Int 
     show1 y 

textshow::IO [Database] 
textshow= do x<-readFile "base.txt" 
      let y=read x::[Database] 
     return y 

show1::Code->IO() 
show1 cd= do o<-textshow 
      let d=[(x,y)|(x,y)<-o,cd==x] 
     putStr(show d) 

ma, il problema è, si sta lavorando bene per i dati singoli, se aggiungo un altro dato, allora mostrando errore Prelude.read: no parse quando sto provando a cercare la voce . L'aiuto sarà apprezzato !!

+0

È possibile aggiungere un input di esempio che attiva il problema? – ibid

+0

ho caricato i/o snap di esempio, per favore dare un'occhiata. –

+1

Ci sono anche problemi di indentazione in textshow e show1. Ma penso che questo mostri il problema. Risposta a breve – ibid

risposta

4

Il tuo problema è nel formato del tuo file di dati. Dopo un uso del textfile, il file contiene il seguente:

[(110,"B")] 

Questa è una buona lista, e funziona. Dopo il secondo uso della textfile, il file contiene il seguente:

[(110,"B")][(110,"B")] 

che non è una buona lista, e non riesce. Si può vedere questo in ghci:

*Main> read "[(110,\"B\")][(110,\"B\")]" :: [Database] 
*** Exception: Prelude.read: no parse 

E 'chiaro che read si aspetta una lista unica, non due liste si susseguono.

Se si desidera aggiungere a un file che contiene un singolo elenco Haskell, è necessario leggere il file, aggiungerlo all'elenco e scrivere il nuovo elenco nel file in sostituzione.

addToFileList :: (Read a, Show a) => FilePath -> a -> IO() 
addToFileList fp a = do olds <- readFile fp `catch` \e -> 
           if isDoesNotExistError e 
           then return "[]" 
           else ioError e 
         let oldl = read olds 
          newl = oldl ++ [a] 
          news = show newl 
         length news `seq` 
           writeFile fp news 

Questo è un po 'difficile a causa di due Tings:

  • readFile è pigro, e writeFile allo stesso file può fallire se non si fa in modo che l'intero file è già stato letto. Nella funzione precedente, questa viene risolta chiedendo la lunghezza della nuova stringa prima di scrivere il file (la funzione seq si assicura che la lunghezza sia calcolata prima che avvenga l'operazione di scrittura).
  • il file potrebbe non esistere, la clausola catch viene utilizzata in precedenza per gestire questo caso eccezionale.