Обновление: поддержка ввода-вывода в более поздних версиях Frege
Начиная с версии 3.21.80, у нас улучшена поддержка ввода-вывода в стандартных библиотеках:
- время выполнения обеспечивает
stdout
и stderr
(буферизованные, кодировка UTF8 java.io.PrintWriters
, обернутые вокруг java.lang.System.out
и java.lang.System.err
) и stdin
(декодирование UTF8 java.io.BufferedReader
, обернутые вокруг java.lang.System.in
) - Функции
print
, println
, putStr
, putChar
запись в stdout
getChar
и getLine
чтение из stdin
и выдача исключений в конце файла. - Эквиваленты Фреге для классов Java, таких как
PrintWriter
, BufferedWriter
и т. Д., Определены в модуле Java.IO
, который автоматически импортируется.При этом поддерживается более базовая функциональность.Например, BufferedReader.readLine
имеет тип возврата IO (Maybe String)
и действительно сообщает о конце файла, возвращая Nothing
, как его Java-аналог, который возвращает null
в таких случаях.
Вот краткий пример программы, которая реализует базовый 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
Поскольку Frege все еще довольно нов, поддержка библиотеки, по общему признанию, все еще отсутствует, несмотря на прогресс, который уже сделан в самой основнойобласти, такие как списки и монады.
Кроме того, хотя цель состоит в том, чтобы обеспечить высокую степень совместимости с Haskell, особенно в системе ввода-вывода и, как правило, в темах, связанных с системой низкого уровня, существует напряженность:Должны ли мы идти по пути Java или действительно пытаться эмулировать путь Haskell (который, в свою очередь, явно зависит от того, что доступно в стандартных библиотеках C / POSIX).
В любом случае, IO, вероятно,Наиболее недоразвитый район библиотеки Фреге, к сожалению.Это также объясняется тем, что относительно легко написать нативные объявления функций для небольшого количества методов Java, которые могут понадобиться специальным образом, вместо того, чтобы тратить время на разработку хорошо продуманной библиотеки.
Кроме того,Класс чтения не существует до сих пор.В качестве замены до тех пор, пока это не будет исправлено, у типа String есть функции для анализа всех типов чисел (на основе методов Java parseXXX ()).
(Примечание: у моих дней также есть только 24 часа, и у меня естьсемью, собаку и работу, о которой нужно заботиться, я был бы очень рад, если бы у меня было больше участников, помогающих улучшить систему Фреге.)
Относительно вашего кода: Да, я считаю, что делать все правильносимвольный ввод / вывод через интерфейсы Reader и Writer.Ваш пример показывает также, что необходимы вспомогательные функции для получения стандартного считывателя ввода.То же самое относится и к стандартному устройству записи вывода.
Однако, когда вам потребуется прочитать более 1 строки, я определенно создаю считыватель в основной функции и передаю его действиям по обработке ввода.