質問

Haskell に相当する Frege はありますか 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

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

役に立ちましたか?

解決

アップデート: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 ファイルの終わりで例外をスローします。
  • 以下のような Java クラスに相当する Frege 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 はまだ非常に新しいため、リストやモナドなどの最も基本的な領域ではすでに進歩しているにもかかわらず、ライブラリのサポートがまだ不足していることは明らかです。

さらに、特に IO システムや一般に低レベルのシステム関連トピックにおいて、Haskell との高度な互換性を持たせることが目的ですが、次のような緊張があります。むしろ Java のやり方を採用するべきでしょうか、それとも Haskell のやり方をエミュレートすることを本当に試みるべきでしょうか (これは、標準 C/POSIX ライブラリで利用可能なものに明らかに影響を受けます)。

いずれにせよ、残念なことに、IO に関するものはおそらく Frege ライブラリの中で最も開発が遅れている領域です。これは、綿密なライブラリを開発するのに時間を費やすことなく、その場限りの方法で必要となる少数の Java メソッドのネイティブ関数宣言をすばやく作成することが比較的簡単だからでもあります。

また、Read クラスは今のところ存在しません。この問題が修正されるまでの代替として、String 型にはすべての数値型を解析する関数があります (Java parseXXX() メソッドに基づく)。

(サイドノート:私の 1 日は 24 時間しかなく、家族、犬、そして大事な仕事があるので、Frege システムの改善に協力してくれる貢献者が増えてくれるととても嬉しいです。)

コードに関して:はい、すべての文字ベースの I/O を Reader および Writer インターフェイスを通じて実行するのが正しいと思います。あなたの例は、標準入力リーダーを取得するための便利な関数が必要であることも示しています。標準出力ライターでも同様です。

ただし、複数行を読み取る必要がある場合は、必ず main 関数でリーダーを作成し、それを入力処理アクションに渡します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top