Domanda

C'è l'equivalente di Frege del getLineGcode di Haskell e readGcode per analizzare l'ingresso dalla console nella biblioteca standard?

Attualmente lo sto facendo così:

import frege.IO

getLine :: IO String
getLine = do
 isin <- stdin
 isrin <- IO.InputStreamReader.new isin
 brin <- IO.BufferedReader.fromISR isrin
 line <- brin.readLine
 return $ fromExceptionMaybe line

fromExceptionMaybe :: Exception (Maybe a) -> a
fromExceptionMaybe (Right (Just r)) = r
fromExceptionMaybe (Right _) = error "Parse error on input"
fromExceptionMaybe (Left l) = error l.getMessage

pure native parseInt java.lang.Integer.parseInt :: String -> Int

main _ = do
 line <- getLine
 println $ parseInt line
.

Aggiornamento:

Frege è stato evoluto così ora abbiamo getLine nella stessa biblioteca standard.Per quanto riguarda read, abbiamo metodi di conversione sulla stringa.Ora il problema originale è semplicemente,

main _ = do
  line <- getLine
  println line.atoi
.

Vedi la risposta di Ingo qui sotto per maggiori dettagli.

È stato utile?

Soluzione

Aggiornamento: supporto I / O in versioni più recenti di Frege

A partire dalla versione 3.21.80, abbiamo un supporto I / O migliore nelle librerie standard:

    .
  • Il runtime fornisce stdout e stderr (buffer, utf8 java.io.PrintWriters avvolto java.lang.System.out e java.lang.System.err) e stdin (UTF8 Decodifica java.io.BufferedReader avvolto in giro java.lang.System.in)
  • Funzioni print, println, putStr, putChar Scrivi a stdout
  • getChar e getLine Leggi da stdin e lanciare eccezioni sulla fine del file.
  • Gli equivalenti di Frege per le classi Java come PrintWriter, BufferedWriter ecc. Sono definiti nel modulo Java.IO, che viene automaticamente importato. Con questo, è supportata più funzionalità di base. Ad esempio, BufferedReader.readLine ha un tipo di restituzione di IO (Maybe String) e segnala la fine del file restituendo Nothing, come la controparte Java, che restituisce null in tali casi.

    Ecco un breve programma di esempio che implementa un grep di base:

    --- A simple grep
    module examples.Grep where
    
    --- exception thrown when an invalid regular expression is compiled
    data PatternSyntax = native java.util.regex.PatternSyntaxException
    derive Exceptional PatternSyntax
    
    main [] = stderr.println "Usage: java examples.Grep regex [files ...]"
    main (pat:xs) = do
            rgx <- return (regforce pat)
            case xs of
                [] -> grepit rgx stdin
                fs -> mapM_ (run rgx) fs
         `catch` badpat where
            badpat :: PatternSyntax -> IO ()
            badpat pse = do
                stderr.println "The regex is not valid."
                stderr.println pse.getMessage        
    
    run regex file = do
            rdr <- utf8Reader file
            grepit regex rdr
        `catch` fnf where
            fnf :: FileNotFoundException -> IO ()
            fnf _ = stderr.println ("Could not read " ++ file)
    
    
    grepit :: Regex -> BufferedReader -> IO ()                
    grepit pat rdr = loop `catch` eof `finally` rdr.close 
        where
            eof :: EOFException -> IO ()
            eof _ = return ()
            loop = do
                line <- rdr.getLine 
                when (line ~ pat) (println line)
                loop
    
    .


    .

    Poiché Frege è ancora abbastanza nuovo, il supporto della biblioteca è certamente mancava ancora, nonostante i progressi già fatti nelle aree più basilari, come elenchi e monade.

    Inoltre, mentre l'intento è quello di avere un alto grado di compatibilità a Haskell, specialmente nel sistema IO e in generale negli argomenti relativi al sistema di basso livello, vi è una tensione: dovremmo piuttosto andare il modo Java o dovremmo Cerchi davvero di emulare il modo di Haskell (che è a sua volta ovviamente influenzato da ciò che è disponibile nelle librerie standard c / posix).

    In ogni caso, la cosa IO è probabilmente l'area più sottosviluppata della Biblioteca di Frege, purtroppo. Questo è anche perché è relativamente facile scrivere rapidamente le dichiarazioni di funzioni native per una manciata di metodi Java, uno avrebbe bisogno in un modo ad hoc, invece di prendersi il tempo per sviluppare una biblioteca benetturiamente fuori.

    Inoltre, una classe di lettura non esiste fino ad ora. Come sostitutivo fino a quando non è stato risolto, il tipo di stringa ha funzioni per analizzare tutti i tipi di numeri (in base ai metodi Java Parsexxx ()).

    (Nota laterale: perché anche i miei giorni hanno solo 24 ore e ho una famiglia, un cane e un lavoro da prendersi cura, sarei molto felice di avere più contributori che aiutano a rendere il sistema di Frege migliore.) Per quanto riguarda il tuo codice: Sì, sento che è giusto fare tutti i I / O basati su personaggio attraverso le interfacce del lettore e dello scrittore. Il tuo esempio mostra anche che sono necessarie funzioni di convenienza per ottenere un lettore di ingresso standard. Lo stesso vale per lo scrittore di uscita standard.

    Tuttavia, quando avresti bisogno di leggere più di 1 riga, creerei sicuramente il lettore nella funzione principale e passeròla alle azioni di elaborazione di ingresso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top