1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2008-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.util
import collection.Seq
/**
* The `Try` type represents a computation that may either result in an exception,
* or return a success value. It's analagous to the `Either` type.
*/
sealed abstract class Try[+T] {
/**
* Returns true if the `Try` is a `Failure`, false otherwise.
*/
def isFailure: Boolean
/**
* Returns true if the `Try` is a `Success`, false otherwise.
*/
def isSuccess: Boolean
/**
* Returns the value from this `Success` or the given argument if this is a `Failure`.
*/
def getOrElse[U >: T](default: => U) = if (isSuccess) get else default
/**
* Returns the value from this `Success` or throws the exception if this is a `Failure`.
*/
def get: T
/**
* Applies the given function f if this is a Result.
*/
def foreach[U](f: T => U): Unit
/**
* Returns the given function applied to the value from this `Success` or returns this if this is a `Failure`.
*/
def flatMap[U](f: T => Try[U]): Try[U]
/**
* Maps the given function to the value from this `Success` or returns this if this is a `Failure`.
*/
def map[U](f: T => U): Try[U]
def collect[U](pf: PartialFunction[T, U]): Try[U]
def exists(p: T => Boolean): Boolean
/**
* Converts this to a `Failure` if the predicate is not satisfied.
*/
def filter(p: T => Boolean): Try[T]
/**
* Converts this to a `Failure` if the predicate is not satisfied.
*/
def filterNot(p: T => Boolean): Try[T] = filter(x => !p(x))
/**
* Calls the exceptionHandler with the exception if this is a `Failure`. This is like `flatMap` for the exception.
*/
def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U]
/**
* Calls the exceptionHandler with the exception if this is a `Failure`. This is like map for the exception.
*/
def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U]
/**
* Returns `None` if this is a `Failure` or a `Some` containing the value if this is a `Success`.
*/
def toOption = if (isSuccess) Some(get) else None
def toSeq = if (isSuccess) Seq(get) else Seq()
/**
* Returns the given function applied to the value from this Success or returns this if this is a `Failure`.
* Alias for `flatMap`.
*/
def andThen[U](f: T => Try[U]): Try[U] = flatMap(f)
/**
* Transforms a nested `Try`, ie, a `Try` of type `Try[Try[T]]`,
* into an un-nested `Try`, ie, a `Try` of type `Try[T]`.
*/
def flatten[U](implicit ev: T <:< Try[U]): Try[U]
def failed: Try[Throwable]
}
final class Failure[+T](val exception: Throwable) extends Try[T] {
def isFailure: Boolean = true
def isSuccess: Boolean = false
def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = {
try {
if (rescueException.isDefinedAt(exception)) rescueException(exception) else this
} catch {
case e2 => Failure(e2)
}
}
def get: T = throw exception
def flatMap[U](f: T => Try[U]): Try[U] = Failure[U](exception)
def flatten[U](implicit ev: T <:< Try[U]): Try[U] = Failure[U](exception)
def foreach[U](f: T => U): Unit = {}
def map[U](f: T => U): Try[U] = Failure[U](exception)
def collect[U](pf: PartialFunction[T, U]): Try[U] = Failure[U](exception)
def filter(p: T => Boolean): Try[T] = this
def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] =
if (rescueException.isDefinedAt(exception)) {
Try(rescueException(exception))
} else {
this
}
def exists(p: T => Boolean): Boolean = false
def failed: Try[Throwable] = Success(exception)
}
final class Success[+T](value: T) extends Try[T] {
def isFailure: Boolean = false
def isSuccess: Boolean = true
def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = Success(value)
def get = value
def flatMap[U](f: T => Try[U]): Try[U] =
try f(value)
catch {
case e => Failure(e)
}
def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
def foreach[U](f: T => U): Unit = f(value)
def map[U](f: T => U): Try[U] = Try[U](f(value))
def collect[U](pf: PartialFunction[T, U]): Try[U] =
if (pf isDefinedAt value) Success(pf(value))
else Failure[U](new NoSuchElementException("Partial function not defined at " + value))
def filter(p: T => Boolean): Try[T] =
if (p(value)) this
else Failure(new NoSuchElementException("Predicate does not hold for " + value))
def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = this
def exists(p: T => Boolean): Boolean = p(value)
def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
}
object Failure {
def apply[T](e: Throwable): Failure[T] = new Failure(e)
def unapply(scrutinizee: Any): Option[Throwable] = scrutinizee match {
case Right(_) => None
case Left(e) => Some(e.asInstanceOf[Throwable])
case s: Success[_] => None
case f: Failure[_] => Some(f.exception)
}
}
object Success {
def apply[T](value: T): Success[T] = new Success(value)
def unapply[T](scrutinizee: Any): Option[T] = scrutinizee match {
case Right(v) => Some(v.asInstanceOf[T])
case Left(_) => None
case s: Success[_] => Some(s.get.asInstanceOf[T])
case f: Failure[Throwable] => None
}
}
object Try {
def apply[T](r: => T): Try[T] = {
try { Success(r) } catch {
case e => Failure(e)
}
}
}
|