2016-12-01 7 views
1

私は現在F#を学びたいと思っており、プログラミングクイズのソースとしてcodingameを使用しています。stdinからの読み込みにはどのような方法がありますか?

ほとんどの場合、stdinの値の最初の10個の値がintであるように、次の5個は文字列になります。

現在、この関数を使用してデータを読み込んでいますが、非常に「un-f#」と感じています。コメントから

let N = 5 
let Reader i = 
    Console.In.ReadLine() 

let words = [0..N-1] |> Seq.map Reader 
+1

あなたの質問は何ですか? –

+0

@ MarkSeemann stdinからN回読むのに良い方法は何ですか? –

+1

私は通常、 'let words = [for _ in 1 ... N - > Console.ReadLine()]'やそのようなもの(ゲームに依存します)を行います。しかし、私は@ MarkSeemannに同意します:質問が何であるか明確ではありません。 –

答えて

4

私は与えられたタイプの特定の番号を読み取るために持っていた場合、私は

open System 

let read parser = 
    Seq.initInfinite (fun _ -> Console.ReadLine()) 
    |> Seq.choose (parser >> function true, v -> Some v | _ -> None) 
のようなものを書きます次いで

let ints = read Int32.TryParse 
let ``ten floats`` = read Double.TryParse |> Seq.take 10 

注場合に使用することができる

210を複数回使用すると、ReadLine()が再度呼び出されます。

let anInt = ints |> Seq.take 1 
printfn "%A" anInt 
printfn "%A" anInt // need to input an int again 

ListまたはSeq.cache。失敗することはありません文字列については、

let strings = read (fun s -> true, s) 

を使用しますが、最小長の要件がある場合:

let potentialPasswords = read (fun s -> s.Length > 10, s) 
+0

あなたがここに示したコンポジションが本当に気に入りました、ありがとう! –

7

、あなたが最も「のF#の-native」(私たちは、「慣用のF#」と呼ぶもの)コンソールからの読み取り方が欲しいことは明らかです。

何を持っていることは慣例により、機能を除いて、十分に慣用され、通常は小文字で始まる:

let reader i = Console.ReadLine() 

プラス、あなたはパラメータを使用していないことから、あなたがする必要はありませんそれに名前を与える:

let reader _ = Console.ReadLine() 

機能が十分に小さい場合は、匿名で、インラインでそれを書くことができます。

let words = [0..N-1] |> Seq.map (fun _ -> Console.ReadLine()) 

また、実際にインデックスを使用していないので、0..N-1の代わりに1..Nとリストを宣言できます。少しきれいに見えます。

最後に、F#が、あなたがより良い可読性を達成するために使用することができ非常に便利なリストの内包表記を提供しています:

let N = 5 
let words = [for _ in 1..N -> Console.ReadLine()] 
+0

非常に素敵な答えをありがとう - データを直接解析する能力が好きなので、私は答えとして他のものを取ってきましたが、あなたの説明はもっと好きでした。 –

+1

F#の特別な 'stdin'値に注意してください。これは' stdin.ReadLine() 'というショートカットとして使うことができます。 'stdout.WriteLine()'もあります。これらの素晴らしい点の1つは、「システムを開く」必要がないことです。 – TheQuickBrownFox

関連する問題