001    package fj;
002    
003    import fj.data.Option;
004    import static fj.data.Option.some;
005    import static fj.data.Option.none;
006    
007    /**
008     * The digits zero to nine.
009     *
010     * @version %build.number%<br>
011     *          <ul>
012     *          <li>$LastChangedRevision: 122 $</li>
013     *          <li>$LastChangedDate: 2009-04-25 08:24:38 +1000 (Sat, 25 Apr 2009) $</li>
014     *          </ul>
015     */
016    public enum Digit {
017      /**
018       * Zero.
019       */
020      _0,
021    
022      /**
023       * One.
024       */
025      _1,
026    
027      /**
028       * Two.
029       */
030      _2,
031    
032      /**
033       * Three.
034       */
035      _3,
036    
037      /**
038       * Four.
039       */
040      _4,
041    
042      /**
043       * Five.
044       */
045      _5,
046    
047      /**
048       * Six.
049       */
050      _6,
051    
052      /**
053       * Seven.
054       */
055      _7,
056    
057      /**
058       * Eight.
059       */
060      _8,
061    
062      /**
063       * Nine.
064       */
065      _9;
066    
067      /**
068       * Converts this digit to a long.
069       *
070       * @return A long for this digit.
071       */
072      public long toLong() {
073        switch (this) {
074          case _0:
075            return 0L;
076          case _1:
077            return 1L;
078          case _2:
079            return 2L;
080          case _3:
081            return 3L;
082          case _4:
083            return 4L;
084          case _5:
085            return 5L;
086          case _6:
087            return 6L;
088          case _7:
089            return 7L;
090          case _8:
091            return 8L;
092          default:
093            return 9L;
094        }
095      }
096    
097      /**
098       * Converts this digit to a character.
099       *
100       * @return A character for this digit.
101       */
102      public char toChar() {
103        switch (this) {
104          case _0:
105            return '0';
106          case _1:
107            return '1';
108          case _2:
109            return '2';
110          case _3:
111            return '3';
112          case _4:
113            return '4';
114          case _5:
115            return '5';
116          case _6:
117            return '6';
118          case _7:
119            return '7';
120          case _8:
121            return '8';
122          default:
123            return '9';
124        }
125      }
126    
127      /**
128       * Converts the right-most digit in the given long value to a digit.
129       *
130       * @param i The long to convert.
131       * @return The right-most digit in the given long value as a digit.
132       */
133      public static Digit fromLong(final long i) {
134        long x = Math.abs(i) % 10L;
135        return x == 0L ? _0 :
136            x == 1L ? _1 :
137                x == 2L ? _2 :
138                    x == 3L ? _3 :
139                        x == 4L ? _4 :
140                            x == 5L ? _5 :
141                                x == 6L ? _6 :
142                                    x == 7L ? _7 :
143                                        x == 8L ? _8 :
144                                            _9;
145      }
146    
147      /**
148       * Converts the given character in the given long value to a digit.
149       *
150       * @param c The character to convert.
151       * @return The character in the given long value as a digit.
152       */
153      public static Option<Digit> fromChar(final char c) {
154        switch (c) {
155          case '0':
156            return some(_0);
157          case '1':
158            return some(_1);
159          case '2':
160            return some(_2);
161          case '3':
162            return some(_3);
163          case '4':
164            return some(_4);
165          case '5':
166            return some(_5);
167          case '6':
168            return some(_6);
169          case '7':
170            return some(_7);
171          case '8':
172            return some(_8);
173          case '9':
174            return some(_9);
175          default:
176            return none();
177        }
178      }
179    
180      /**
181       * First-class conversion from digit to a long.
182       */
183      public static final F<Digit, Long> toLong = new F<Digit, Long>() {
184        public Long f(final Digit d) {
185          return d.toLong();
186        }
187      };
188    
189      /**
190       * First-class conversion from a long to a digit.
191       */
192      public static final F<Long, Digit> fromLong = new F<Long, Digit>() {
193        public Digit f(final Long i) {
194          return fromLong(i);
195        }
196      };
197    
198      /**
199       * First-class conversion from a digit to a character.
200       */
201      public static final F<Digit, Character> toChar = new F<Digit, Character>() {
202        public Character f(final Digit d) {
203          return d.toChar();
204        }
205      };
206    
207      /**
208       * First-class conversion from a character to a digit.
209       */
210      public static final F<Character, Option<Digit>> fromChar = new F<Character, Option<Digit>>() {
211        public Option<Digit> f(final Character c) {
212          return fromChar(c);
213        }
214      };
215    }