更新:Fregeの最新バージョンでのI/Oサポート
バージョン3.21.80の時点で、標準ライブラリでのI/Oサポートが向上しています。
- ランタイムは
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
例外をスローします。
PrintWriter
などのようなJavaクラスに相当するFregeBufferedWriter
は、モジュールJava.IO
で定義され、自動的にインポートされます。これにより、より基本的な機能がサポートされます。たとえばBufferedReader.readLine
、はの戻り型を持ち、そのような場合に戻るJavaの対応物のように、を返すIO (Maybe String)
ことによってファイルの終わりを通知します。Nothing
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はまだ非常に新しいため、リストやモナドなどの最も基本的な領域ですでに進歩が見られているにもかかわらず、ライブラリのサポートはまだ不足していることは確かです。
さらに、特にIOシステムおよび一般的に低レベルのシステム関連のトピックでHaskellとの高度な互換性を持たせることを目的としていますが、緊張があります。 Haskellの方法をエミュレートします(これは、標準のC / POSIXライブラリで利用できるものに明らかに影響されます)。
とにかく、残念ながら、IOのことはおそらくフレーゲライブラリの中で最も開発が進んでいない領域です。これはまた、ライブラリを十分に開発するために時間をかける代わりに、アドホックな方法で必要となる少数のJavaメソッドのネイティブ関数宣言をすばやく作成するのが比較的簡単だからです。
また、Readクラスは今のところ存在しません。これが修正されるまでの代替として、String型には、すべての数値型を解析する関数があります(Java parseXXX()メソッドに基づく)。
(補足:私の日々も24時間しかなく、家族、犬、そして世話をする仕事があるので、Fregeシステムの改善に役立つ貢献者が増えれば幸いです。)
コードに関して:はい、リーダーとライターのインターフェイスを介してすべての文字ベースのI/Oを実行するのが正しいと思います。あなたの例は、標準の入力リーダーを取得するための便利な機能が必要であることも示しています。同じことが標準の出力ライターにも当てはまります。
ただし、複数行を読み取る必要がある場合は、main関数でリーダーを作成し、それを入力処理アクションに渡します。