Language.Haskell.Interpreter
まず第一に、これを行うためにヒントパッケージを使用することは (少なくとも明白な方法では) できません。そのモジュールのその関数は、任意の構造化データではなく、Haskell コードを読み込んで実行するために使用されます。
構造化データを読み取るには、何らかのパーサーが必要です。以下にいくつかのオプションを示します。
- Happyなどのパーサー ジェネレーターを使用します。
- uu-parsinglibやparsecなどのパーサー コンビネーター ライブラリを使用します。
- 独自のパーサーを直接実装します。
- クラスの自動派生インスタンスを利用します
Read
。
広告 1. と 2.
読み込む必要があるデータの形式が重要である場合、または解析が失敗した場合に役立つエラー メッセージが必要な場合は、1. または 2. を選択し、それぞれのツールとライブラリのドキュメントを参照することをお勧めします。それらの主な概念とインターフェイスに慣れるには、ある程度の時間がかかることに注意してください。
広告 3.
データの形式が十分に単純で (例のように)、広範なエラー レポートが希望リストの上位にない場合は、独自のパーサーを簡単に作成できます。
あなたの例では、構成ファイルは基本的に改行で区切られたキーと値のリストです。Haskell では、このようなリストを文字列のペアのリストで表すことができます。
type Config = [(String, String)]
構成を「解析」すると、次のようになります。(1) 入力文字列を行に分割する、(2) 各行を単語に分割する、(3) 各行から最初と 3 番目の単語を選択する:
readConfig :: String -> Config
readConfig s =
[(key, val) | line <- lines s, let (key : _ : val : _) = words line]
解析された構成ファイルからエントリを取得するには、関数を使用できますget
。
get :: String -> (String -> a) -> Config -> a
get key f config = case lookup key config of
Nothing -> error ("get: not found: " ++ key)
Just x -> f x
この関数は、最初の引数としてエントリのキーを受け取り、2 番目の引数として生の値の文字列を適切な型に変換する関数を受け取ります。純粋にテキストの構成値の場合、アイデンティティ関数を に渡すだけですget
。
inputFile, outputFile, datefmt :: Config -> String
inputFile = get "inputFile" id
outputFile = get "outputFile" id
datefmt = get "datefmt" id
整数エントリの場合、次を使用できますread
。
numRecords, numFields :: Config -> Int
numRecords = get "numRecords" read
numFields = get "numFields" read
おそらく、これらのパターンは、 の独自の専用バージョンに分解するのに十分一般的ですget
。
getS :: String -> Config -> String
getS key = get key id
getR :: Read a => String -> Config -> a
getR key = get key read
inputFile', outputFile', datefmt' :: Config -> String
inputFile' = getS "inputFile"
outputFile' = getS "outputFile"
datefmt' = getS "datefmt"
numRecords', numFields' :: Config -> Int
numRecords' = getR "numRecords"
numFields' = getR "numFields"
例として、構成ファイルを読み取り、「outputFile」の値を出力するプログラムを次に示します。
main :: IO ()
main = do
s <- readFile "config.txt"
let config = readConfig s
putStrLn (outputFile config)
広告 4。
構成ファイルの形式を制御できる場合は、構成データを保持するための新しいデータ型を導入し、Haskell にそのクラスのインスタンスを自動的に派生させることができますRead
。例えば:
data Config = Config
{ numRecords :: Int
, numFields :: Int
, inputFile :: String
, outputFile :: String
, datefmt :: String
} deriving Read
ここで、構成ファイルが予想される形式と一致していることを確認する必要があります。例えば:
Config
{ numRecords = 10
, numFields = 3
, inputFile = "/home/user1/project/indata.file"
, outputFile = "/home/user1/project/outdata.file"
, datefmt = "ddmmyyyy"
}
例として、「outputFile」の値を出力するプログラムを次に示します。
main :: IO ()
main = do
s <- readFile "config.txt"
let config = read s
putStrLn (outputFile config)