Frege es el equivalente de Haskell del getLine y leer
-
13-11-2019 - |
Pregunta
Es allí cualquier Frege es el equivalente de Haskell del getLine
y read
para analizar la entrada de la consola en la biblioteca estándar?
Actualmente estoy trabajando como este:
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
Actualización:
Frege se ha desarrollado hasta ahora hemos getLine
en la biblioteca estándar de sí mismo.Como para read
, tenemos métodos de conversión en la Cadena.Ahora el problema original es simplemente,
main _ = do
line <- getLine
println line.atoi
Ver Ingo la respuesta de abajo para más detalles.
Solución
Actualización:Soporte de e/S en las versiones más recientes de Frege
A partir de la versión 3.21.80, tenemos un mejor soporte de e/S en las bibliotecas estándar:
- El tiempo de ejecución proporciona
stdout
ystderr
(buffer, la codificación UTF8java.io.PrintWriters
envuelto alrededor dejava.lang.System.out
yjava.lang.System.err
) ystdin
(UTF8 decodificaciónjava.io.BufferedReader
envuelto alrededor dejava.lang.System.in
) - Funciones
print
,println
,putStr
,putChar
escribir astdout
getChar
ygetLine
lectura destdin
y lanzar excepciones en el final del archivo.- El Frege equivalentes para las clases de Java como
PrintWriter
,BufferedWriter
etc.están definidos en el móduloJava.IO
, que se importan automáticamente.Con esto, más la funcionalidad básica es compatible.Por ejemplo,BufferedReader.readLine
tiene un tipo de retorno deIO (Maybe String)
y hace la señal de la final de archivo mediante la devolución deNothing
, igual que el de Java contraparte, que devuelvenull
en tales casos.
Aquí es un breve ejemplo de programa que implementa un básico grep:
--- 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
Porque Frege es todavía bastante nuevo, el soporte de la biblioteca es verdad que aún falta, a pesar de los avances que ya se ha hecho en la mayoría de las áreas básicas, como las Listas y las Mónadas.
Además, aunque la intención es tener un alto grado de compatibilidad para Haskell, especialmente en el sistema de e / s y, en general, el bajo nivel del sistema de temas relacionados, existe una tensión:Debemos ir por el Java manera o debemos tratar de emular Haskell la forma (que es a su vez obviamente influenciado por lo que está disponible en el estándar de C/POSIX bibliotecas).
De todos modos, el IO cosa es probablemente el más subdesarrollado área de Frege de la biblioteca, por desgracia.Esto también es debido a que es relativamente fácil de escribir rápidamente nativo de las declaraciones de función para un puñado de métodos Java se necesita de una manera ad hoc, en lugar de tomar el tiempo para desarrollar un bien fuera de la biblioteca.
También, una clase de Lectura no existe hasta ahora.Como substiutute hasta que este ha sido un fijo, el tipo de Cadena tiene funciones para analizar todos los tipos de números (basado en Java parseXXX() métodos).
(Nota al margen:Porque mis días sólo tienen 24 horas y tengo una familia, un perro y un trabajo sobre el cuidado, yo sería muy feliz de tener más colaboradores que ayudan a hacer que el sistema de Frege mejor).
Con respecto a su código:Sí, creo que es correcto hacer todos los caracteres de e/S a través de la lectura y escritura de las interfaces.Su ejemplo muestra también que las funciones de comodidad para la obtención de un estándar de entrada de lector son necesarios.Lo mismo vale para la salida estándar escritor.
Sin embargo, cuando se tendría que leer más de 1 línea, me gustaría definitivamente crear en el lector la función principal y de paso a la entrada de procesamiento de acciones.