Digit
数字を表します。
Digitオブジェクトにこれを継承した0から9までの数字が定義されています。
toInt, toChar, toLong
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Digit._ | |
_1.toInt assert_=== 1 | |
_9.toChar assert_=== '9' | |
_0.toLong assert_=== 0L |
Digits
DigitsにはdigitsとLongからDigit、DigitからLongへ変換するimplicit conversionが定義されています。
digitsは_0から_9までをもつListです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1L |+| _1 assert_=== 2L | |
digits(1) |+| 1L assert_=== _2 |
MA#digits, MA#traverseDigits, MA#longDigits
digitsはコンテナが内包するCharをDigitへ変換します。
変換に成功した場合はSome、失敗の場合はNoneが返されます。
traverseDigitsは成功した場合、コンテナがSomeで包まれます。
longDigitsは内包されたDigitをLongへ畳み込みます。
この時先頭の0は無視されます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"1a3".show.digits assert_=== List(Some(_1), None, Some(_3)) | |
"12a".show.traverseDigits assert_=== None | |
"123".show.traverseDigits assert_=== Some(List(_1, _2, _3)) | |
digits.longDigits assert_=== 123456789L |
最後にたかはしさんからforkしたコード。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scalaz._ | |
import Scalaz._ | |
import scala.util.parsing.combinator._ | |
object KanjiNumberParser extends RegexParsers { | |
def one = "一" ^^^ digits(1) | |
def two = "二" ^^^ digits(2) | |
def three = "三" ^^^ digits(3) | |
def four = "四" ^^^ digits(4) | |
def five = "五" ^^^ digits(5) | |
def six = "六" ^^^ digits(6) | |
def seven = "七" ^^^ digits(7) | |
def eight = "八" ^^^ digits(8) | |
def nine = "九" ^^^ digits(9) | |
def oneDigit: Parser[Digit] = one | two | three | four | five | six | seven | eight | nine | |
def ju = opt(oneDigit) <~ "十" ^^ { _ | digits(1) } | |
def hyaku = opt(oneDigit) <~ "百" ^^ { _ | digits(1) } | |
def sen = opt(oneDigit) <~ "千" ^^ { _ | digits(1) } | |
def threeDigits = opt(sen) ~ opt(hyaku) ~ opt(ju) ~ opt(oneDigit) ^^ { | |
case a ~ b ~ c ~ d => (a +>: b +>: c +>: d +>: nil).map(_.orZero) | |
} | |
def man = opt(threeDigits) <~ "万" ^^ { _ | 10000L.digits } | |
def oku = opt(threeDigits) <~ "億" ^^ { _ | (10000L * 10000L).digits } | |
def cho = opt(threeDigits) <~ "兆" ^^ { _ | (10000L * 10000L * 10000L).digits } | |
def kanjiNumber = opt(cho) ~ opt(oku) ~ opt(man) ~ opt(threeDigits) ^^ { | |
case a ~ b ~ c ~ d => ~(a |+| b |+| c |+| d) | |
} | |
def parse(in: String) = parseAll(kanjiNumber, in) | |
} | |
object Main extends App { | |
KanjiNumberParser.parse("千五百兆二千二億三千五百十九万百一").map(_.longDigits assert_=== 1500200235190101L).getOrElse(throw new RuntimeException) | |
} |
ただDigitを使ってみたかっただけ。
数をListとして操作できるのも面白いなと思いました。
0 件のコメント:
コメントを投稿