Вопрос

Есть ли эквивалент Фреге Хаскеля? getLine и read анализировать ввод с консоли в стандартной библиотеке?

На данный момент я делаю это так:

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

Обновлять:

Фреге был развит, и теперь у нас есть getLine в самой стандартной библиотеке.Что касается read, у нас есть методы преобразования для String.Теперь исходная проблема проста:

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

Более подробную информацию смотрите в ответе Инго ниже.

Это было полезно?

Решение

Обновлять:Поддержка ввода-вывода в более поздних версиях 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

Поскольку Фреге все еще довольно новичок, поддержка библиотеки, по общему признанию, все еще отсутствует, несмотря на прогресс, уже достигнутый в самых основных областях, таких как списки и монады.

Кроме того, хотя целью является обеспечение высокой степени совместимости с Haskell, особенно в системе ввода-вывода и вообще в темах, связанных с системой низкого уровня, существует противоречие:Стоит ли нам идти по пути Java или действительно попытаться подражать пути Haskell (на который, в свою очередь, очевидно влияет то, что доступно в стандартных библиотеках C/POSIX).

В любом случае, к сожалению, область ввода-вывода — это, пожалуй, самая недоработанная область библиотеки Фреге.Это также связано с тем, что относительно легко быстро написать собственные объявления функций для нескольких методов Java, которые могут понадобиться в индивидуальном порядке, вместо того, чтобы тратить время на разработку хорошо продуманной библиотеки.

Кроме того, до сих пор не существует класса Read.В качестве замены, пока это не будет исправлено, тип String имеет функции для анализа всех типов чисел (на основе методов Java parseXXX()).

(Примечание:Поскольку в моих сутках тоже всего 24 часа, а у меня есть семья, собака и работа, о которой нужно заботиться, я был бы очень рад, если бы у меня было больше участников, которые помогут сделать систему Фреге лучше.)

Что касается вашего кода:Да, я считаю правильным выполнять весь символьный ввод-вывод через интерфейсы Reader и Writer.Ваш пример также показывает, что необходимы удобные функции для получения устройства чтения стандартного ввода.То же самое справедливо и для средства записи стандартного вывода.

Однако, когда вам нужно прочитать более 1 строки, я бы определенно создал средство чтения в основной функции и передал его действиям по обработке ввода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top