こちらは、意外とすぐにできたので。StringWです。
charsNel(e: ⇒ NonEmptyList[Char])
元のStringが空文字であれば、引数で渡された関数の返却値であるNonEmptyListが返ります。そうでなければ、元のStringをNonEmptyListに変換したものが返ります。
println("hello charsNel => " + "hello".charsNel("default".toList.toNel.get)) println("[] charsNel => " + "".charsNel("default".toList.toNel.get))
実行結果。
hello charsNel => NonEmptyList(h, e, l, l, o) [] charsNel => NonEmptyList(d, e, f, a, u, l, t)
charsNel
引数無し版です。元のStringが空文字であればNoneが、そうでなければSomeに包まれたNonEmptyListが返ります。
println("hello charsNel => " + "hello".charsNel) println("[] charsNel => " + "".charsNel)
実行結果。
hello charsNel => Some(NonEmptyList(h, e, l, l, o)) [] charsNel => None
charsNelErr
元のStringが空文字であれば、RuntimeExceptionがスローされ引数の文字列が例外メッセージになります。そうでければ、NotEmptyListにStringが変換されます。
println("hello charsNelErr => " + "hello".charsNelErr("Not Empty")) println("hello charsNelErr => " + { try { "".charsNelErr("Empty") } catch { case e: RuntimeException => e.getMessage } })
実行結果。
hello charsNelErr => NonEmptyList(h, e, l, l, o) hello charsNelErr => Empty
encode
暗黙のパラメータが必要です。StringをArray[Byte]に変換します。
implicit val c = charset("UTF-8") println("日本語 encode => " + new String("日本語".encode, "UTF-8")) println("[] encode => " + new String("".encode, "UTF-8"))
なお、charset関数はScalaz.CharSetを返す関数です。
実行結果。
日本語 encode => 日本語 [] encode =>
fileEach
元のStringをファイル名として使い、ファイルを開いて1バイトずつ読み込みます。引数は、Byteを受けるコールバック関数。
import scala.collection.mutable.ArrayBuffer val buffer = new ArrayBuffer[Byte] "src/main/scala/StringExample.scala".fileEach(b => buffer += b) println(new String(buffer.toArray, "UTF-8")) // このソースが出力される
なお、ファイルが存在しなかった場合は、java.io.FileNotFoundExceptionがスローされます。ソースを見た限り、これ系のメソッドはバッファリングされていないっぽいので微妙…。
実行結果。
/* ファイルの内容が出力されるサンプルのため、割愛 */
node(prefix: String, a: Option)
StringからXMLノードを作成します。元のStringはタグ名になり、第2引数にSomeを渡すと値として使用されます。
println("tag node => " + { "tag".node("prefix", some("value")) } + ", " + { "tag".node("prefix", none[String]) }) println("[] node => " + { "".node("prefix", some("value")) } + ", " + { "".node("prefix", none[String]) })
実行結果。
tag node => <prefix:tag>value</prefix:tag>, [] node => <prefix:>value</prefix:>,
特に元の文字が空文字でも、エラーになったりせずタグ名が空になります。また、第2引数のOptionをNoneにすると、結果自体がなくなります。
node(prefix: String, attributes: MetaData, scope: NamespaceBinding, a: Option)
属性、名前空間が指定できるnodeメソッドっぽいのですが…。
println("tag node => " + { "tag".node("prefix", null, null, some("value")) }) println("[] node => " + { "".node("prefix", null, null, some("value")) })
実行結果。
tag node => <prefix:tag>value</prefix:tag> [] node => <prefix:>value</prefix:>
ソースを見る限り、引数を使っているかどうか微妙…。
StringW.scala
/** * Construct an XML node based on the given option value. If there is no value available, then an empty text node is returned, * otherwise, the string representation (using show) of the value is returned in an element with the given label. */ def node[A: Show](prefix: String, attributes: MetaData, scope: NamespaceBinding, a: Option[A]): Node = a match { case Some(t) => Elem(prefix, s, Null, TopScope, t.text) case None => Text("") }
parseBoolean
元のStringがBooleanとして解析しようと試みます。結果はValidationとして返されます。
"true".parseBoolean.foreach { bool => printf("Boolean parsed[%b]\n", bool) } "hoge".parseBoolean.foreach { bool => printf("Boolean parsed[%b]\n", bool) }
実行結果。
Boolean parsed[true]
例えば、Validation#foreachを使用すると、解析に失敗した場合は引数に渡した関数は実行されせん。
parseByte
parseBooleanと同様。
"10".parseByte.foreach { b => printf("Byte parse[%d]\n", b) } "ten".parseByte.foreach { b => printf("Byte parse[%d]\n", b) }
実行結果。
Byte parse[10]
parseDouble, parseFloat, parseInt, parseLong, parseShort
割愛します。しかし、なぜかparseCharはありません。
plural
複数形に変更した文字列を返します。引数は、数を表し、1つならそのまま、2以上なら複数形になります。
println("book plural => " + "book".plural(1)) println("book plural => " + "book".plural(2)) println("[] plural => " + "".plural(2))
実行結果。
book plural => book book plural => books [] plural => s
とはいえ、辞書とかを内部に持っているわけではないので、複雑なルールなどには対応してません。
readFile
初期値と累積値および1バイトを受け取る引数を取り、ファイルを読み込みます。要は、ファイル版foldLeftです。
println("src/main/scala/StringExample.scala".readFile("", (s: String, b: Byte) => s + b.toChar)) // もちろん、これだと日本語は化けます
実行結果。
/* ファイルの内容が出力されるサンプルのため、割愛 */
readLines
1行辺りの初期値、行ごとの累積値と1文字、ファイル全体の初期値、行ごとの累積値と1行を引数にファイルを行単位に読み込みます。戻り値はUnitなので、結果は返せません。ここでは、行ヘッダとして「readLines:」を付けています。
"src/main/scala/StringExample.scala".readLines("readLines:", (xacc: String, c: Char) => { xacc + c }, "", (yacc: String, line: String) => { println(line) yacc })
実行結果。
/* 割愛 */ readLines: // readLines readLines: "src/main/scala/StringExample.scala".readLines("readLines:", readLines: (xacc: String, c: Char) => { xacc + c }, readLines: "", readLines: (yacc: String, line: String) => { readLines: println(line) readLines: yacc readLines: }) /* 割愛 */
ちなみに、CRとLFは意識していますがCRLFは意識していないっぽいので、CRLFのファイルに対してBufferedReader#readLine的な感覚で使うと、LFを受けた時に空文字を受け取ることになります。
s
元の文字列が取れます。
println("hello.s => " + "hello".s) println("[].s => " + "".s)
実行結果。
hello.s => hello [].s =>
unsafeCharsNel
元のStringを直接NonEmptyListに変換します。元のStringが空文字だった場合は、RuntimeExceptionがスローされます。
println("hello unsafeCharsNel => " + "hello".unsafeCharsNel) println("[] unsafeCharsNel => " + { try { "".unsafeCharsNel } catch { case e: RuntimeException => e.getMessage } })
実行結果。
hello unsafeCharsNel => NonEmptyList(h, e, l, l, o) [] unsafeCharsNel => cannot turn empty string into NonEmptyList
要は、例外メッセージが決まっているcharsNelErrメソッドです。実際の実相もそうなっています。
|:|
XMLノードを作成します。prefix指定無しのnodeメソッドと同義です。
println("hello |:| => " + "hello".|:|(some("value"))) println("[] |:| => " + "".|:|(some("value")))
hello |:| => <hello>value</hello> [] |:| => <>value</>
XML系の機能と、ファイルの読み込み機能はちょっと怪しい感じですね。特にファイル読み込み機能はかなり微妙です。改行コードの扱いが変とか、バッファリングしてないとか、CharSetの指定ができないとか…。NonEmptyListへの変換とparse系のメソッドを使う感じかなぁ。
これで一応、目標にしていたBooleanW、IntW、ListW、OptionW、StringWは一通り見て回りました。