2 hello 3
a
b
c
d
hoge1 fuga1
hoge2 fuga2
という入力を想定する。
以下のval sampleInput
が同等の価値を生む。
(|
はstripMargin
が行頭を判断するためのものなので気にしないで大丈夫です)
val sampleInput =
"""|2 hello 3
|a
|b
|c
|d
|hoge1 fuga1
|hoge2 fuga2""".stripMargin
(for {
(num1, str1, num2) <- Reader.readOneLine[(Int, String, Int)]
str2 <- Reader.one[String]
strArray <- Reader.listOfN[String](num2)
strTupleArray <- Reader.readMultipleLine[(String, String)](num1)
} yield (num1, str1, num2, str2, strArray, strTupleArray))
.run(sampleInput.toList)
._1
.tap(println)
$ sbt run
(2,hello,3,a,List(b, c, d),List((hoge1,fuga1), (hoge2,fuga2)))
1mmも外部ライブラリに依存してないのでMain.scala
をコピペすればどこでも動くはずです
Reader.one[A]: Reader[A] ... スペースあるいは改行を見つけるまで文字を結合しAに型変換する
Reader.listOfN[A](n: Int): Reader[List[A]] ... Reader.one[A]をn回実行する
Reader.readOneLine[A]: Reader[A] ... 改行を見つけるまで文字を結合しAに型変換する
Reader.readMultipleLine[A](n: Int): Reader[List[A]] ... Reader.readOneLine[A]をn回実行する
A
に変換できなかった場合は例外を投げます。
Reader.one[Int].run("1".toList) ... OK
Reader.one[Int].run("hello".toList) ... Error
Tuple2, Tuple3まで対応した。競プロで1行に4つ並んでいて尚且つそれが複数列になってるところを見たことなかったので
Reader.readOneLine[(Int, String)].run("1 hoge".toList) ... OK
Reader.readOneLine[(Int, String, Int)].run("1 hoge 23".toList) ... OK
Reader.readOneLine[(Int, String, Int, String)].run("1 hoge 23 fuga".toList) ... NG: 未対応