15

フレーゲのハスケルに相当するものはあり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

アップデート:

Fregeは進化したので、今getLineでは標準ライブラリ自体にあります。についてreadは、Stringの変換メソッドがあります。さて、元の問題は単純です、

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

詳細については、以下のIngoの回答を参照してください。

4

1 に答える 1

12

更新:Fregeの最新バージョンでのI/Oサポート

バージョン3.21.80の時点で、標準ライブラリでのI/Oサポートが向上しています。

  • ランタイムはstdoutstderr(バッファリングされた、UTF8エンコーディングjava.io.PrintWritersがラップアラウンドjava.lang.System.outされたjava.lang.System.err)およびstdin(UTF8デコーディングjava.io.BufferedReaderがラップアラウンドされたjava.lang.System.in)を提供します
  • 関数print、、、printlnputStrputChar書き込みstdout
  • getCharファイルの終わりからgetLine読み取り、stdin例外をスローします。
  • PrintWriterなどのようなJavaクラスに相当するFregeBufferedWriterは、モジュールJava.IOで定義され、自動的にインポートされます。これにより、より基本的な機能がサポートされます。たとえばBufferedReader.readLine、はの戻り型を持ち、そのような場合に戻るJavaの対応物のように、を返すIO (Maybe String)ことによってファイルの終わりを通知します。Nothingnull

基本的な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関数でリーダーを作成し、それを入力処理アクションに渡します。

于 2012-02-27T15:46:19.507 に答える