2017-02-15 3 views
3

12 34 56のような入力をHaskellを使って3つの整数に読みたいと思っています。Haskellのstdinから3つの連続する整数を読み込むには?

単一の整数の場合、myInteger <- readLnを使用することがあります。その後、非常にハック感じたread '[' ++ str ++ ']'を呼ぶ:しかし、このような場合のために、私は最初の1は、,ですべてのスペースを置き換える(

spaceToCommas str = 
    let repl ' ' = ',' 
     repl c = c 
    in map repl str 

のようなものを使用して)、その後、ラインを読み除いて、任意の解決策を見つけていません。また、私はの3つのの整数を読みたいと述べることはできません。の整数をstdinから読み取ろうとします。

もっと良い方法があるはずです。

ではなく、は外部パッケージを使用してください。たとえばを使用します。 Parsecはもちろん素晴らしいですが、この単純な例では本格的なParser Combinatorフレームワークを使用する必要はありません。以下のような文字列を変換について

+0

doブロックで 'readLn'を3回呼び出すだけではどうですか?あるいは、副作用のあるマップを使用し、長さ3の範囲をマップし、関数内で 'readLn'を呼び出します。それは3つのintのリストを返します。 – Carcigenicate

+0

1行から3つの整数を読み込みますか?入力は通常、ラインバッファリングされています - 1行に4つの整数がある場合はどうなりますか? 2つだけの場合はどうなりますか? – Carl

+0

ああ、一行読んでみたいですか?どうしてそちらをスペースで分割して読んでみませんか? – Carcigenicate

答えて

4

何:

convert :: Read a => String -> [a] 
convert = map read . words 

wordsは、文字列のリストに指定した文字列を分割し(「言葉」)し、我々はmapを使用してすべての要素にreadを行います。

とインスタンスのようにそれを使用する:あなたは、例えば最初の3つの要素を読みたいと(はい、これは明らかにスーパー -creativityのスキルが必要です)、残りを気にしない場合

main = do 
    line <- getLine 
    let [a,b,c] = convert line :: [Int] in putStrLn (show (c,a,b)) 

をか:

main = do 
    line <- getLine 
    let (a:b:c:_) = convert line :: [Int] in putStrLn (show (c,a,b)) 

ここでは、解析が完了したことを示すために右に1つ回転したタプルが返されました。

+0

これはstdinから3つの整数を読み取るわけではありません。これは単に行をつかみ、それをすべて読み込もうとしますが、正確に3つではない場合はパターン一致エラーで失敗します。 ( "また、3つの整数を読みたいと述べているわけではありませんが、stdinから任意の量の整数を読み込もうとします。") – user2407038

+0

@ user2407038:それ自体は ' map'は怠惰です( '' map''の要素の 'fx'も同様に怠惰です)。さらに、創造性*のちょっとしたビットを使って、2つ、4つ、または任意の整数のシナリオを実装できます:) 。 –

+0

パターンマッチでこれを正しく使うには?ユーザー・エラー(Prelude.readIO:なしパース) ' – Qqwy

関連する問題